<?xml version="1.0" encoding="UTF-8"?>
<!--XSLT Processor: Saxonica-->
<!--XSLT Processor: Saxonica-->
<!DOCTYPE spec
  SYSTEM "../../../schema/xsl-query.dtd">
<spec xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"
      id="spec-top"
      w3c-doctype="rec"
      status="ext-review">
   <header id="id-spec-header">
      <title>XQuery 4.0: An XML Query Language</title>
      <version/>
      <w3c-designation>REC-xquery-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/xquery-40/"
              xlink:type="simple"
              xlink:show="replace"
              xlink:actuate="onRequest">https://qt4cg.org/specifications/xquery-40/</loc>
      </publoc>
      <!-- These altlocs URIs are computed from the concatenation of doc.public, doc.shortname, and either '.xml' or
     '-diff-from-yyyymmdd.html', where 'yyyymmdd' is the earlier version of the spec from which a diff has been produced -->
      <altlocs>
         <loc xmlns:xlink="http://www.w3.org/1999/xlink"
              href="xquery-40.xml"
              xlink:type="simple"
              xlink:show="replace"
              xlink:actuate="onRequest">XML</loc>
      </altlocs>
      <!-- The latestloc URI is computed from doc.latestloc -->
      <!--<latestloc doc="&language;">
  <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="&doc.latestloc;" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">&doc.latestloc;</loc>
</latestloc>-->
      <!-- These prevlocs URIs are always hard-coded and are never computed from entities -->
      <!-- Pubrules doesn't like FPWD to have a prevloc, not even a previous Recommendation -->
      <!--<prevlocs doc="&language;">
  <loc role="xquery" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2017/PR-xquery-31-20170117/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2017/PR-xquery-31-20170117/</loc>
  <loc role="xquery" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2016/CR-xquery-31-20161213/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2016/CR-xquery-31-20161213/</loc>
  <loc role="xquery" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2015/CR-xquery-31-20151217/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2015/CR-xquery-31-20151217/</loc>
  <loc role="xquery" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2014/CR-xquery-31-20141218/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2014/CR-xquery-31-20141218/</loc>
  <loc role="xquery" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2014/WD-xquery-31-20141007/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2014/WD-xquery-31-20141007/</loc>
  <loc role="xquery" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2014/WD-xquery-31-20140424/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2014/WD-xquery-31-20140424/</loc>
  <loc role="xpath" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2017/PR-xpath-31-20170117/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2017/PR-xpath-31-20170117/</loc>
  <loc role="xpath" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2016/CR-xpath-31-20161213/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2016/CR-xpath-31-20161213/</loc>
  <loc role="xpath" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2015/CR-xpath-31-20151217/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2015/CR-xpath-31-20151217/</loc>
  <loc role="xpath" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2014/CR-xpath-31-20141218/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2014/CR-xpath-31-20141218/</loc>
  <loc role="xpath" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2014/WD-xpath-31-20141007/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2014/WD-xpath-31-20141007/</loc>
  <loc role="xpath" xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2014/WD-xpath-31-20140424/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2014/WD-xpath-31-20140424/</loc>
</prevlocs>
-->
      <!--
<latestloc-major doc="&language-major;">
  <loc href="&doc.latestloc-major;">&doc.latestloc-major;</loc>
</latestloc-major>
-->
      <latestloc-tech doc="XQuery">
         <loc xmlns:xlink="http://www.w3.org/1999/xlink"
              href="https://qt4cg.org/specifications/xquery-40/"
              xlink:type="simple"
              xlink:show="replace"
              xlink:actuate="onRequest">https://qt4cg.org/specifications/xquery-40/</loc>
      </latestloc-tech>
      <prevrec doc="XQuery">
         <loc xmlns:xlink="http://www.w3.org/1999/xlink"
              role="xquery"
              href="https://www.w3.org/TR/2017/REC-xquery-31-20170321/"
              xlink:type="simple"
              xlink:show="replace"
              xlink:actuate="onRequest">https://www.w3.org/TR/2017/REC-xquery-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 role="xquery">The publications of this community group 
<loc xmlns:xlink="http://www.w3.org/1999/xlink"
                    href="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>
      <!--* N.B. the value of the errataloc href attribute is set in
    * ../style/assemble-spec.xsl
    * when the XQuery or XPath spec is assembled.  If it changes,
    * change it THERE.
    *-->
      <!--<errataloc
 role="spec-conditional"
 href="https://www.w3.org/XML/2017/qt-errata/xquery-31-errata.html"
 xlink:type="simple"/>


<translationloc
 role="spec-conditional"
 href="http://www.w3.org/2003/03/Translations/byTechnology?technology=xquery-31"/>
-->
      <!--&status-section;-->
      <!--<status>
    <p>This is a draft prepared by the QT4CG (officially registered in W3C as the
      XSLT Extensions Community Group). Comments are invited.</p>
-->
      <!--</status>-->
      <abstract id="id-abstract">
         <p role="xquery">XML is a versatile markup language, capable of labeling the
information content of diverse data sources, including structured and
semi-structured documents, relational databases, and object
repositories. A query language that uses the structure of XML
intelligently can express queries across all these kinds of data,
whether physically stored in XML or viewed as XML via middleware.
This specification describes a query language called XQuery, which is
designed to be broadly applicable across many types of XML data
sources.</p>
         <p role="xquery" diff="add">A list of changes made since XQuery 3.1 can be found in <specref ref="id-revision-log"/>. 
</p>
      </abstract>
      <langusage>
         <language id="EN">English</language>
         <!--
<language id="ebnf">EBNF</language>
-->
      </langusage>
      <revisiondesc id="id-DOESNOTEXIST">
         <slist>
            <sitem>XQuery 4.0 First Public Working Draft. (#####)</sitem>
         </slist>
      </revisiondesc>
   </header>
   <body>
      <div1 id="id-introduction">
         <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.</change>
         </changes>
         <p role="xquery">As increasing amounts of information are stored, exchanged, and presented using
		XML, the ability to intelligently query XML data sources becomes increasingly important. One
		of the great strengths of XML is its flexibility in representing many different kinds of
		information from diverse sources. To exploit this flexibility, an XML query language must
	provide features for retrieving and interpreting information from these diverse sources.</p>
         <p role="xquery">As increasing amounts of JSON are used for lightweight data-exchange, an XML query language
	for Web data needs to handle JSON as well as XML and HTML.</p>
         <p role="xquery" diff="chg" at="2023-10-19">XQuery is designed to be a language in which queries are concise and
		easily understood. It is also flexible enough to query a broad spectrum of information
		sources, both XML and non-XML, including both databases and documents. XQuery was originally derived from an XML query
		language called Quilt <bibref ref="Quilt"/>, which in turn borrowed features from several
		other languages, including XPath 1.0 <bibref ref="xpath"/>, XQL <bibref ref="XQL"/>, XML-QL
			<bibref ref="XML-QL"/>, SQL <bibref ref="SQL"/>, and OQL <bibref ref="ODMG"/>. </p>
         <p>
            <termdef id="dt-datamodel" term="data model">XQuery 4.0 operates on the abstract, logical
			structure of an XML document or JSON object rather than its surface syntax. This logical structure,
			known as the <term>data model</term>, is defined in <bibref ref="xpath-datamodel-40"/>.</termdef>
         </p>
         <p>
            <phrase role="xquery">XQuery 4.0 is an extension of XPath 4.0.</phrase>
          

 In general, any expression that is
		syntactically valid and executes successfully in both XPath 4.0 and XQuery 4.0 will return
		the same result in both languages. There are a few exceptions to this rule: <ulist>
               <item>
                  <p>Because XQuery expands <phrase role="xquery">
                        <termref def="dt-predefined-entity-reference">predefined entity
							references</termref> and <termref def="dt-character-reference">character
							references</termref>
                     </phrase>
					 and XPath does not, expressions containing these produce different
					results in the two languages. For instance, the value of the string literal
						<code role="parse-test" nobreak="false">"&amp;amp;"</code> is <code nobreak="false">&amp;</code> in XQuery,
					and <code nobreak="false">&amp;amp;</code> in XPath. (A host language may expand predefined entity references or character references
					before the XPath expression is evaluated.)</p>
               </item>
               <item>
                  <p>If XPath 1.0 compatibility mode is enabled, XPath behaves differently from
					XQuery in a number of ways, 
					<phrase role="xquery">which are discussed in <bibref ref="xpath-40"/>.</phrase>
                  </p>
               </item>
            </ulist>
         </p>
         <p>Because these languages are so closely related, their grammars and language descriptions are
		generated from a common source to ensure consistency.</p>
         <p>XQuery 4.0 also depends on and is closely related to the following specifications:</p>
         <ulist>
            <item>
               <p>
                  <bibref ref="xpath-datamodel-40"/> defines the data model that underlies all
				XQuery 4.0 expressions.</p>
            </item>
            <item>
               <p>The type system of XQuery 4.0 is based on XML Schema. It is implementation-defined
				whether the type system is based on <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/>.</p>
            </item>
            <item>
               <p>The system function library and the operators supported by XQuery 4.0 are defined
				in <bibref ref="xpath-functions-40"/>.</p>
            </item>
            <item role="xquery" diff="del" at="2023-10-19">
               <p>XQuery also has an XML-based syntax, which is described in [XQueryX 3.1]. </p>
            </item>
         </ulist>
         <note diff="add" at="2023-10-19">
            <p>The XML-based syntax for XQuery known as XQueryX
		is no longer maintained.</p>
         </note>
         <p role="xquery">
            <termdef id="dt-xquery-40-processor"
                     term="XQuery 4.0 Processor"
                     diff="add"
                     at="2023-10-19"> An <term>XQuery 4.0
			Processor</term> processes a query according to the XQuery 4.0 specification. </termdef>
            <termdef id="dt-xquery-31-processor" term="XQuery 3.1 Processor"> An <term>XQuery 3.1
				Processor</term> processes a query according to the XQuery 3.1 specification. </termdef>
            <termdef id="dt-xquery-30-processor" term="XQuery 3.0 Processor"> An <term>XQuery 3.0
				Processor</term> processes a query according to the XQuery 3.0 specification. </termdef>
            <termdef id="dt-xquery-10-processor" term="XQuery 1.0 Processor"> An <term>XQuery 1.0
				Processor</term> processes a query according to the XQuery 1.0 specification.
		</termdef>
         </p>
         <p>This document specifies a grammar for XQuery 4.0, using the same basic EBNF notation used in
			<bibref ref="XML"/>. Unless otherwise noted (see <specref ref="lexical-structure"/>),
		whitespace is not significant in <phrase role="xquery">queries</phrase>. Grammar productions are introduced together with the features
		that they describe, and a complete grammar is also presented in the appendix [<specref ref="nt-bnf"/>]. The appendix is the normative version.</p>
         <p>In the grammar productions in this document, named symbols are underlined and literal text is
		enclosed in double quotes. For example, the following productions describe the syntax of a
		static function call:</p>
         <scrap role="example" headstyle="show">
            <prod id="example-example-doc-xquery40-FunctionCall">
               <lhs>FunctionCall</lhs>
               <rhs>
                  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                  <nt def="prod-xquery40-ArgumentList">ArgumentList<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
               <com>
                  <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
               </com>
               <com>
                  <loc href="#parse-note-parens">gn: parens</loc>
               </com>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-EQName">
               <lhs>EQName</lhs>
               <rhs>
                  <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-ArgumentList">
               <lhs>ArgumentList</lhs>
               <rhs>"("  ((<nt def="prod-xquery40-PositionalArguments">PositionalArguments<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-KeywordArguments">KeywordArguments<!--$idref_lang_part = xquery40- --></nt>)?)  |  <nt def="prod-xquery40-KeywordArguments">KeywordArguments<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-PositionalArguments">
               <lhs>PositionalArguments</lhs>
               <rhs>(<nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-Argument">
               <lhs>Argument</lhs>
               <rhs>
                  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholder<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-ExprSingle">
               <lhs>ExprSingle</lhs>
               <rhs>
                  <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-ArgumentPlaceholder">
               <lhs>ArgumentPlaceholder</lhs>
               <rhs>"?"</rhs>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-KeywordArguments">
               <lhs>KeywordArguments</lhs>
               <rhs>(<nt def="prod-xquery40-KeywordArgument">KeywordArgument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
            </prod>

            <prod id="example-example-doc-xquery40-FunctionCall-KeywordArgument">
               <lhs>KeywordArgument</lhs>
               <rhs>
                  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ":="  <nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>
         </scrap>
         <p>The productions should be read as follows: A function call consists of an <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt> followed by an <nt def="prod-xquery40-ArgumentList">ArgumentList<!--$spec = xquery40--></nt>. The
		argument list consists of an opening parenthesis, an optional list of one or more arguments
		(separated by commas), and a closing parenthesis.</p>
         <p>This document normatively defines the static and dynamic semantics of XQuery 4.0. In this
		document, examples and material labeled as “Note” are provided for explanatory purposes and
		are not normative.</p>
      </div1>
      <div1 id="id-basics">
         <head>Basics</head>
         <div2 id="id-terminology">
            <head>Terminology</head>
            <changes>
               <change issue="1366" PR="1498">The EBNF operators <code nobreak="false">++</code> and <code nobreak="false">**</code>
      have been introduced, for more concise representation of sequences using a character
      such as <code nobreak="false">","</code> as a separator. The notation is borrowed from Invisible XML.</change>
            </changes>
            <p>The basic building block of XQuery 4.0 is the
	 <term>expression</term>, which is a string of <bibref ref="Unicode"/> characters; the version of Unicode to be used is <termref def="dt-implementation-defined">implementation-defined</termref>.
	 The language provides several kinds of expressions which may be constructed
	 from keywords, symbols, and operands. In general, the operands of an expression
	 are other expressions. XQuery 4.0 allows expressions to be nested with full
generality. <phrase role="xquery">(However, unlike a pure functional
language, it does not allow variable substitution if the variable
declaration contains construction of new nodes.)</phrase>
            </p>
            <note>
               <p>This specification contains no
assumptions or requirements regarding the character set encoding of strings
of <bibref ref="Unicode"/> characters.</p>
            </note>
            <p>Like XML, XQuery 4.0 is a case-sensitive language. Keywords in
	 XQuery 4.0 use lower-case characters and are not reserved—that is, names in XQuery 4.0 expressions are allowed to be the same as language keywords, except for certain unprefixed function-names listed in <specref ref="id-reserved-fn-names"/>.</p>
            <p>In this specification the phrases <rfc2119>must</rfc2119>, <rfc2119>must
                  not</rfc2119>, <rfc2119>should</rfc2119>, <rfc2119>should not</rfc2119>,
                  <rfc2119>may</rfc2119>, <rfc2119>required</rfc2119>, and
                  <rfc2119>recommended</rfc2119>, when used in normative
                  text and rendered in small capitals, are to be interpreted as described in
                  <bibref ref="RFC2119"/>.</p>
            <p>Certain aspects of language processing are described in this specification as
			<term>implementation-defined</term> or <term>implementation-dependent</term>.</p>
            <ulist>
               <item>
                  <p>
                     <termdef id="dt-implementation-defined" term="implementation defined">
                        <term>Implementation-defined</term> indicates an aspect that may differ
					between implementations, but must be specified by the implementer for each
					particular implementation.</termdef>
                  </p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-implementation-dependent" term="implementation   dependent">
                        <term>Implementation-dependent</term> indicates an aspect that may differ
					between implementations, is not specified by this or any W3C specification, and
					is not required to be specified by the implementer for any particular
					implementation.</termdef>
                  </p>
               </item>
            </ulist>
            <div3 id="id-ebnf-introduction">
               <head>Grammar Notation</head>
               <changes>
                  <change issue="1366" PR="1498" date="2024-10-30">
                  The EBNF notation has been extended to allow the constructs <code nobreak="false">(A ++ ",")</code>
                  (one or more occurrences of <code nobreak="false">A</code>, comma-separated, and <code nobreak="false">(A ** ",")</code>
                  (zero or more occurrences of <code nobreak="false">A</code>, comma-separated.
               </change>
               </changes>
               <p>The grammar of XQuery 4.0 is defined using a version of EBNF defined
            in <specref ref="EBNFNotation"/>. The notation is based on the EBNF dialect used in the
            XML specification, with two notable additions derived from the Invisible XML grammar:</p>
               <p>
                  <code nobreak="false">(A ++ ",")</code> represents a sequence of one or more comma-separated
               occurrences of <code nobreak="false">A</code>.</p>
               <p>
                  <code nobreak="false">(A ** ",")</code> represents a sequence of zero or more comma-separated
               occurrences of <code nobreak="false">A</code>.</p>
               <p>For example the following production rule indicates that an <code nobreak="false">Expr</code>
            consists of one or more occurrences of <code nobreak="false">ExprSingle</code>, separated by commas:</p>
               <scrap role="example" headstyle="show">
                  <prod id="example-example-doc-xquery40-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="example-example-doc-xquery40-Expr-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>In principle any production can be used for the separator, but in practice this notation
            is only used in cases where the separator is a simple constant string.</p>
               <p>EBNF grammar rules appear throughout the specification for ease of reference, and the
            entire grammar is summarized in <specref ref="id-grammar"/>.
            
            <phrase role="xquery">For XQuery 4.0, the top-level production rule is 
            <nt def="doc-xquery40-Module">Module<!--$spec = xquery40--></nt>, representing an XQuery module.</phrase>
               </p>
            </div3>
            <div3 id="id-expression-names">
               <head>Expression Names</head>
               <changes>
                  <change issue="2084" PR="2115" date="2025-07-23">
                  This section describes and formalizes a convention that was already in use,
                  but not explicitly stated, in earlier versions of the specification.
               </change>
               </changes>
               <p>Many grammatical production rules for expressions 
               take a form similar to:</p>
               <scrap role="example" headstyle="show">
                  <prod id="example-example-doc-xquery40-RangeExpr">
                     <lhs>RangeExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>  ("to"  <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="example-example-doc-xquery40-RangeExpr-AdditiveExpr">
                     <lhs>AdditiveExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>  (("+"  |  "-")  <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>
               </scrap>
               <p>In describing the semantics of the language, we adopt the convention that a
               term such as <term>range expression</term> (written in bold, or hyperlinked to its definition)
               refers to a non-trivial instance of the production named <nt def="doc-xquery40-RangeExpr">RangeExpr<!--$spec = xquery40--></nt>. More
               specifically, it refers to an instance of the production in which the optional part
               (<code nobreak="false">to AdditiveExpr</code>) is actually present. The construct <code nobreak="false">$n + 1</code>,
               being an <nt def="doc-xquery40-AdditiveExpr">AdditiveExpr<!--$spec = xquery40--></nt>, is technically an instance of <nt def="doc-xquery40-RangeExpr">RangeExpr<!--$spec = xquery40--></nt>,
               but it is not a <term>range expression</term> under this definition.</p>
               <p>
                  <termdef id="dt-non-trivial" term="non-trivial">A construct is said to be a
            <term>non-trivial</term> instance of a grammatical production if it is not also
            an instance of one of its sub-productions.</termdef>
               </p>
            </div3>
            <div3 id="id-values">
               <head>Values</head>
               <changes>
                  <change issue="1337" PR="1361" date="2024-08-02">
               The term <term>atomic value</term> has been replaced by <termref def="dt-atomic-item"/>.
            </change>
                  <change issue="2025" PR="2031" date="2025-06-13">
               The terms <term>XNode</term> and <code nobreak="false">JNode</code> are introduced; the existing
               term <term>node</term> remains in use as a synonym for <term>XNode</term> where
               the context does not specify otherwise.
            </change>
               </changes>
               <p>
                  <termdef term="value" id="dt-value">In the <termref def="dt-datamodel">data model</termref>, a <term>value</term> is always a <termref def="dt-sequence">sequence</termref>.</termdef>
               </p>
               <p>
                  <termdef id="dt-sequence" term="sequence">A
<term>sequence</term> is an ordered collection of zero or more
<termref def="dt-item">items</termref>.</termdef>
               </p>
               <p>
                  <termdef id="dt-item" term="item">
  An <term>item</term> is either an <termref def="dt-atomic-item">atomic item</termref>, a <termref def="dt-node">node</termref>,
or a <termref def="dt-function-item">function item</termref>.</termdef>
               </p>
               <p>
                  <termdef id="dt-atomic-item" term="atomic item">An <term>atomic
	 item</term> is a value in the value space of an <term>atomic
	 type</term>, as defined in <bibref ref="XMLSchema10"/>  or <bibref ref="XMLSchema11"/>.</termdef>
               </p>
               <p>
                  <termdef id="dt-XNode" term="XNode">An <term>XNode</term> is an instance of one of the
	  <term>node kinds</term> defined in <xspecref spec="DM40" ref="nodes"/>.</termdef>
Each XNode has a unique <term>node identity</term>, a <term>typed value</term>, and a <term>string value</term>. 
            In addition, some XNodes have a <term>name</term>. The <term>typed value</term> of an XNode is a sequence
	 of zero or more atomic items. The <term>string value</term> of an XNode is a
	 value of type <code nobreak="false">xs:string</code>. The <term>name</term> of an XNode is a value of type <code nobreak="false">xs:QName</code>.</p>
               <p>
                  <termdef id="dt-node" term="node">Except where the context indicates otherwise, the term
         <term>node</term> is used as a synonym for <termref def="dt-XNode"/>.</termdef>
               </p>
               <p>
                  <termdef id="dt-JNode" term="JNode">A <term>JNode</term> (see also <xspecref spec="DM40" ref="id-JNodes"/>) 
         is an encapsulation of a value as it appears within a tree of maps and arrays, typically (but not necessarily)
         obtained by parsing JSON texts.</termdef>
               </p>
               <p>
                  <termdef id="dt-GNode" term="GNode">A <term>GNode</term> (for <emph>generalized node</emph>)
               is either an <termref def="dt-XNode"/> or a <termref def="dt-JNode"/>.</termdef>
               </p>
               <p>
                  <termdef id="dt-function-item" term="function item">A <term>function item</term> is an item that can
         be called using a <termref def="dt-dynamic-function-call"/>.</termdef>
               </p>
               <p>Maps (see <specref ref="id-maps"/>) and arrays (see <specref ref="id-arrays"/>) are
         specific kinds of <termref def="dt-function-item"/>s.</p>
               <p>
                  <termdef id="dt-singleton" term="singleton">A sequence containing exactly one item is called a
	 <term>singleton</term>.</termdef> An item is identical to a singleton sequence
	 containing that item. Sequences are never nested—for example, combining the
	 values 1, (2, 3), and ( ) into a single sequence results in the sequence (1, 2,
	 3). </p>
               <p>
                  <termdef id="dt-empty-sequence" term="empty sequence">The sequence containing zero items is called the <term>empty sequence</term>.</termdef>
               </p>
               <p>
                  <termdef id="dt-data-model-instance" term="XDM instance">The term <term>XDM instance</term> is used,
    synonymously with the term <termref def="dt-value">value</termref>, to denote an unconstrained
    <termref def="dt-sequence">sequence</termref> of <termref def="dt-item">items</termref>.</termdef>
               </p>
               <!-- -->
            </div3>
            <div3 id="id-namespaces-and-qnames">
               <head>Namespaces and QNames</head>
               <changes>
                  <change role="xquery" issue="485 2178" PR="487">In XQuery 4.0, an initial set of
            namespace bindings is prescribed for the static context.</change>
                  <change issue="2079" PR="2227" date="2025-10-03">A <code nobreak="false">URIQualifiedName</code> may now supply a prefix
            as well as a URI and local name.</change>
               </changes>
               <p>
                  <termdef id="dt-namespace-binding" term="namespace binding">A <term>namespace binding</term>
         is a pair comprising a namespace prefix (which is either an <code nobreak="false">xs:NCName</code> or empty),
         and a namespace URI.</termdef>
               </p>
               <p>Element nodes have a property called <term>in-scope namespaces</term>. <termdef term="in-scope namespaces" id="dt-in-scope-namespaces">The <term>in-scope namespaces</term> property of an element node is a set of 
         <termref def="dt-namespace-binding">namespace bindings</termref>, each of which associates a namespace prefix with a URI.</termdef>
For a given element, one namespace binding may have an empty prefix; the URI of this namespace binding is 
referred to as the <termref def="dt-default-in-scope-namespace"/> for the element.</p>
               <note role="xquery">
                  <p>In <bibref ref="xpath"/>, the in-scope namespaces of an element node are represented by a collection of <term>namespace nodes</term>
            arranged on a <term>namespace axis</term>, which is optional and deprecated in <bibref ref="xpath-40"/>. XQuery does not support the namespace axis and does not represent namespace bindings in the form of nodes.</p>
                  <p>However, where other specifications such as <bibref ref="xslt-xquery-serialization-40"/> refer to namespace nodes, these nodes may be synthesized from the in-scope namespaces of 
            an element node by interpreting each <termref def="dt-namespace-binding"/> as a namespace node. An application that 
            needs to create a set of namespace nodes to represent these bindings for an element bound to 
            <code nobreak="false">$e</code> can do so using the following code.


<eg role="parse-test" xml:space="preserve">
for key $k value $v in in-scope-namespaces($e)
return namespace {$k}{$v} 
</eg>
                  </p>
               </note>
               <p>
                  <termdef id="dt-default-in-scope-namespace" term="default in-scope namespace">The <term>default in-scope namespace</term>
         of an element node</termdef> is the namespace URI to which the empty prefix is bound in the element’s 
         <termref def="dt-in-scope-namespaces"/>. In the absence of an explicit binding for the empty prefix, the
         default in-scope namespace is <xtermref spec="DM40" ref="dt-absent"/>.</p>
               <p>
                  <termdef id="dt-expanded-qname" term="expanded QName">An <term>expanded QName</term> is a
      triple: its components are a prefix, a local name, and a
      namespace URI. In the case of a name in no namespace, the
      namespace URI and prefix are both absent. In the case of a name
      in the default namespace, the prefix is absent.</termdef> When
      comparing two expanded QNames, the prefixes are ignored: the
      local name parts must be equal under the Unicode codepoint
      collation (<xspecref spec="FO40" ref="collations"/>), 
      and the namespace URI parts must either both be
      absent, or must be equal under the Unicode codepoint
      collation.</p>
               <note>
                  <p>The <xtermref spec="DM40" ref="dt-datum"/> of 
            an <termref def="dt-atomic-item"/> of type <code nobreak="false">xs:QName</code>
            is an <termref def="dt-expanded-qname"/>. However, the
            term <termref def="dt-expanded-qname"/> is also used for
            the names of constructs such as functions, variables, and types
            that are not themselves atomic items.</p>
               </note>
               <p>In the XQuery 4.0
      grammar, QNames representing the names of
      elements, attributes, functions, variables, types, or other such
      constructs are written as instances of the grammatical
      production <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt>.</p>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-EQName-URIQualifiedName">
                     <lhs>URIQualifiedName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":")?  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-EQName-BracedURILiteral">
                     <lhs>BracedURILiteral</lhs>
                     <rhs>"Q"  "{"  (<nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  [^&amp;{}])*  "}"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>
               </scrap>
               <p>The <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt> production allows a QName to
      be written in one of four ways:
      <ulist>
                     <item>
                        <p>local-name only (for example, <code nobreak="false">invoice</code>).</p>
                        <p>A name written in this form has no prefix, and the rules
        for determining the namespace depend on the context in which
        the name appears: the various rules used are summarized
        in <specref ref="id-expanding-unprefixed-qnames"/>.
                  This form is a <termref def="dt-qname">lexical QName</termref>.</p>
                     </item>
                     <item>
                        <p>prefix plus local-name (for example, <code nobreak="false">my:invoice</code>).</p>
                        <p>In this case the prefix and local name of the QName are as
        written, and the namespace URI is inferred from the prefix by
        examining the <termref def="dt-static-namespaces"/> in the static context where
        the QName appears; the context must include a binding for the
        prefix. This form is a <termref def="dt-qname">lexical
        QName</termref>.</p>
                     </item>
                     <item>
                        <p>URI plus local-name (for example,
        <code nobreak="false">Q{http://example.com/ns}invoice</code>).</p>
                        <p>In this case the local name and namespace URI are as
        written, and the prefix is absent. This way of writing a QName
        is context-free, which makes it particularly suitable for use
        in  <phrase role="xquery">queries</phrase>
            
        that are generated by software. This
        form is a <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$spec = xquery40--></nt>.  
        If the <nt def="prod-xquery40-BracedURILiteral">
        BracedURILiteral<!--$spec = xquery40--></nt> has no content (for example, <code nobreak="false">Q{}invoice</code>) 
        then the namespace URI of the QName is absent.</p>
                     </item>
                     <item>
                        <p>URI plus prefix plus local-name (for example,
        <code nobreak="false">Q{http://example.com/ns}xmp:invoice</code>).</p>
                        <p>In this case all three components of the expanded QName are
                  present. Although in most contexts the prefix will be ignored,
                  there may be cases where it is useful, for example if the QName
                  is cast to a string.</p>
                        <p>It is a static error <errorref class="ST" code="0154"/> 
                  if the prefix is present and the namespace URI
               is absent (for example <code nobreak="false">Q{}xmp:invoice</code>).</p>
                     </item>
                  </ulist>
               </p>
               <p>
                  <termdef id="dt-qname" term="lexical QName">A
          <term>lexical QName</term> is a name that conforms to the syntax of the
          <nt def="prod-xquery40-QName">QName<!--$spec = xquery40--></nt> production</termdef>.
          </p>
               <p>
	  The namespace URI value in a <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$spec = xquery40--></nt> is whitespace normalized according
	  to the rules for the <code nobreak="false">xs:anyURI</code> type in
          <xspecref spec="XS1-2" ref="anyURI"/> or 
          <xspecref spec="XS11-2" ref="anyURI"/>. 

          It is a <termref def="dt-static-error">static
          error</termref>
                  <errorref class="ST" code="0070"/> if the
          namespace URI for an EQName is
          <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.
          </p>
               <p>Here are some examples of <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt>s:</p>
               <ulist>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">pi</code> is a <termref def="dt-qname">lexical QName</termref> without a namespace prefix.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">math:pi</code> is a <termref def="dt-qname">lexical QName</termref> with a namespace prefix.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">Q{http://www.w3.org/2005/xpath-functions/math}pi</code> specifies the namespace URI using a  <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$spec = xquery40--></nt>; it is not a  <termref def="dt-qname">lexical QName</termref>.</p>
                  </item>
               </ulist>
               <p>This document uses the following namespace prefixes to represent the namespace URIs 
         with which they are listed.</p>
               <ulist>
                  <item role="xquery">
                     <p>
                        <code nobreak="false">xml</code>: <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">xs</code>: <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>
                     </p>
                  </item>
                  <item role="xquery">
                     <p>
                        <code nobreak="false">xsi</code>: <code nobreak="false">http://www.w3.org/2001/XMLSchema-instance</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">fn</code>: <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">array</code>: <code nobreak="false">http://www.w3.org/2005/xpath-functions/array</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">map</code>: <code nobreak="false">http://www.w3.org/2005/xpath-functions/map</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">math</code>: <code nobreak="false">http://www.w3.org/2005/xpath-functions/math</code>
                     </p>
                  </item>
                  <item diff="add" at="2023-05-10">
                     <p>
                        <code nobreak="false">err</code>: <code nobreak="false">http://www.w3.org/2005/xqt-errors</code>
                  (see <specref ref="id-identifying-errors"/>).</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <code nobreak="false">local</code>: <code nobreak="false">http://www.w3.org/2005/xquery-local-functions</code>
                  (see <specref ref="FunctionDeclns"/>.)
            </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">output</code>: <code nobreak="false">http://www.w3.org/2010/xslt-xquery-serialization</code>
                     </p>
                  </item>
                  <item role="xquery" diff="add" at="2023-12-14">
                     <p>
                        <code nobreak="false">xq</code>: <code nobreak="false">http://www.w3.org/2012/xquery</code>
                     </p>
                  </item>
               </ulist>
               <p role="xquery">In XQuery 4.0, the above namespace bindings are by default included
      in the <termref def="dt-static-namespaces"/> of the <termref def="dt-static-context"/> 
      of every query module; however, these bindings can be overridden in the query prolog.</p>
               <p>
                  <termdef term="URI" id="dt-URI">Within this specification, the term <term>URI</term> refers to a Universal Resource Identifier as defined in <bibref ref="RFC3986"/> and extended in <bibref ref="RFC3987"/> with the new name <term>IRI</term>.</termdef>
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.</p>
               <note>
                  <p>In most contexts, processors are not required to raise errors if a URI is not lexically valid according to  <bibref ref="RFC3986"/> and  <bibref ref="RFC3987"/>. See <specref ref="id-uri-literals"/>
                     <phrase role="xquery">and <specref ref="id-namespaces"/>
                     </phrase> for details.</p>
               </note>
            </div3>
            <div3 id="id-expanding-unprefixed-qnames">
               <head>Expanding Lexical QNames</head>
               <p>When a <termref def="dt-qname"/> appearing in an XQuery 4.0 expression is expanded, the rules are as follows.</p>
               <p>If the name contains a colon, then the prefix (the substring before the colon) is used to establish the 
               corresponding URI by reference to the <termref def="dt-static-namespaces"/>
            in the <termref def="dt-static-context"/>. If there
                  is no binding for the prefix in the <termref def="dt-static-namespaces"/> then
                  a static error is raised <errorref class="ST" code="0081"/>.
            </p>
               <p>If the <termref def="dt-qname">lexical QName</termref> contains no colon (and therefore no prefix),
            the namespace URI part of the QName is inferred in one of a number of ways, depending on the syntactic context
            in which the name appears. The various rules are defined below, and are referred to throughout the specification.</p>
               <ulist>
                  <item>
                     <p>
                        <termdef id="dt-no-namespace-rule" term="no-namespace rule">When an unprefixed lexical QName
               is expanded using the <term>no-namespace rule</term>, it is interpreted as having an absent namespace URI.</termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-default-function-namespace-rule"
                                 term="default function namespace rule">When 
                     an unprefixed lexical QName
                     is expanded using the <term>default function namespace rule</term>, 
                     the processor searches for a matching function definition as follows: 
                     first, if the static context includes a no-namespace function definition 
                     with the required local name and arity, then that function definition is used; 
                     otherwise, the name is expanded using the <termref def="dt-default-function-namespace"/> from 
                     the <termref def="dt-static-context"/>.</termdef>
                     </p>
                     <note>
                        <p>The implication of this rule is that if there is a user-defined function in no namespace
                  with the same local name as a system-defined function in the <code nobreak="false">fn</code>
                     namespace, then a function call using the unprefixed function name invokes the user-defined
                     function in preference to the system-defined function.</p>
                        <p>It is generally advisable to avoid any danger of user confusion by keeping the names
                        of user-defined functions noticably distinct from the names of system-defined functions,
                        for example by using different naming conventions (for example, leading upper-case letters
                        leading underscores, or <code nobreak="false">camelCase</code>).</p>
                        <p>There may however be cases where a user-defined function deliberately has the same local name
                        as a system-defined function, but with modified semantics. For example a user might choose
                        to define a function <code nobreak="false">Q{}current-date()</code> that returns a date with no timezone:
                        this might be defined in XQuery as:</p>
                        <eg xml:space="preserve">declare function current-date() as xs:date {
   fn:current-date() =&gt; fn:adjust-date-to-timezone(())
}</eg>
                     </note>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-default-type-namespace-rule" term="default type namespace rule">When 
                  an unprefixed lexical QName
               is expanded using the <term>default type namespace rule</term>, it uses the 
                  <termref def="dt-default-namespace-elements-and-types"/>. If this is absent, the <termref def="dt-no-namespace-rule"/>
                  is used. If the <termref def="dt-default-namespace-elements-and-types"/> has the special value <code nobreak="false">##any</code>,
                  then the lexical QName refers to a name in the namespace <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>.</termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-default-element-namespace-rule"
                                 term="default element namespace rule">When 
                  an unprefixed lexical QName
               is expanded using the <term>default element namespace rule</term>, then it uses the 
                  <termref def="dt-default-namespace-elements-and-types"/>. If this is absent, or if it takes
                  the special value <code nobreak="false">##any</code>, then the <termref def="dt-no-namespace-rule"/>
                  is used.</termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-constructed-element-namespace-rule"
                                 term="constructed element namespace rule">
                  When  an unprefixed lexical QName
               is expanded using the <term>constructed element namespace rule</term>, then it uses the namespace URI
                     that is bound to the empty (zero-length) prefix in the <termref def="dt-static-namespaces"/> of the
                     <termref def="dt-static-context"/>. If there is no such <termref def="dt-namespace-binding"/>
                  then it uses the <termref def="dt-no-namespace-rule"/>.</termdef>
                     </p>
                  </item>
                  <item role="xquery">
                     <p>
                        <termdef id="dt-default-annotation-namespace-rule"
                                 term="default annotation namespace rule">
                  When  an unprefixed lexical QName
               is expanded using the <term>annotation namespace rule</term>, then it uses the namespace URI
                     <code nobreak="false">http://www.w3.org/2012/xquery</code>.</termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-element-name-matching-rule" term="element name matching rule">When 
                  an unprefixed lexical QName
               is expanded using the <term>element name matching rule</term>, then it uses the 
                  <termref def="dt-default-namespace-elements-and-types"/>. If this is absent, then 
                  it uses the <termref def="dt-no-namespace-rule"/>. But if it takes the special value <code nobreak="false">##any</code>,
                  then the name is taken as matching any <termref def="dt-expanded-qname"/> with the corresponding local part,
                  regardless of namespace: that is, the  unprefixed name <code nobreak="false">local</code> is interpreted
                  as <code nobreak="false">*:local</code>.</termdef>
                     </p>
                  </item>
               </ulist>
            </div3>
         </div2>
         <div2 id="context">
            <head>Expression Context</head>
            <p>
               <termdef id="dt-expression-context" term="expression context">The <term>expression
		context</term> for a given expression consists of all
		the information that can affect the result of the
		expression.</termdef>
            </p>
            <p>This information is organized into two categories
		called the <termref def="dt-static-context">static
		context</termref> and the <termref def="dt-dynamic-context">dynamic
		context</termref>.</p>
            <!--<p role="xquery">
            <termdef id="dt-module-context" term="module context"
               >The <term>module context</term> for a given
		module consists of all the information that is
		accessible to top-level expressions in the
		module.</termdef> The context of a top-level
		expression is defined based on the context of the
		module in which it is defined: the context of the <nt
               def="QueryBody"
            >QueryBody</nt> is the context of the
		main module, and the context for evaluating a function
		body or for a variable’s initializing expression is
		defined based on the context of the module in which
		the function or variable is defined.</p>-->
            <div3 id="static_context">
               <head>Static Context</head>
               <changes>
                  <change issue="296" PR="1181" date="2024-04-30">
                  The <termref def="dt-default-namespace-elements-and-types"/> can be set to the value <code nobreak="false">##any</code>,
                  allowing unprefixed names in axis steps to match elements with a given local name in any namespace.
               </change>
                  <change issue="1343" PR="1344" date="2024-09-23">

                  Parts of the static context that were there purely to assist in static typing, such as the statically
                  known documents, were no longer referenced and have therefore been dropped.
               </change>
                  <change issue="1495" PR="1496" date="2024-10-29">
                  The context value static type, which was there purely to assist in static typing, has been dropped.
               </change>
                  <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>
                  <termdef id="dt-static-context" term="static context">The <term>static context</term> of an expression is
		  the information that is available during static analysis of the expression, prior
		  to its evaluation.</termdef> This information can be used to decide whether the
		  expression contains a <termref def="dt-static-error">static error</termref>. </p>
               <p>The individual components of the <termref def="dt-static-context">static context</termref> are described below.</p>
               <p role="xquery">In XQuery 4.0, the static context for an expression is largely defined
               in the query prolog of a module: see <specref ref="id-query-prolog"/>. Declarations in the 
               prolog, such as variable declarations, function declarations, and decimal format declarations
               populate the static context for expressions appearing within the module. In some cases (but
               not all) these declarations may affect the static context for expressions that precede
               the relevant declaration. The static context can also be affected by declarations in other
               modules that are referenced using an <code nobreak="false">import module</code> declaration: see
               <specref ref="id-module-import"/>.</p>
               <p role="xquery">In addition, some expressions modify the static context for their subexpressions.
               The most obvious example is <termref def="dt-in-scope-variables"/>
               (a <nt def="doc-xquery40-FLWORExpr">FLWORExpr<!--$spec = xquery40--></nt> declares bindings of local variables that are available
               for reference within subsequent clauses of the expression). A further example is the
               <termref def="dt-static-namespaces"/>: an element constructor may contain namespace declarations
               such as <code nobreak="false">xmlns:p="some_uri"</code> which cause additional namespace prefixes to be available
               within the content of the element constructor.</p>
               <p role="xquery">Appendix <specref ref="id-xq-static-context-components"/> gives an overview
               of the components in the static context and the way they are initialized.</p>
               <p>Some components of the static context, but not all, also affect the dynamic semantics
            of expressions. For example, casting of a string such as <code nobreak="false">"xbrl:xbrl"</code> to
            an <code nobreak="false">xs:QName</code> might expand the prefix <code nobreak="false">xbrl</code> to the namespace
            URI <code nobreak="false">http://www.xbrl.org/2003/instance</code> using the <termref def="dt-static-namespaces"/>
               from the static context;
            since the input string <code nobreak="false">"xbrl:xbrl"</code> is in general not known until execution time (it
            might be read from a source document), this means that the values of the 
            <termref def="dt-static-namespaces"/> must be available at execution time.</p>
               <ulist>
                  <item>
                     <p>
                        <termdef id="dt-xpath-compat-mode" term="XPath 1.0 compatibility     mode">
                           <term>XPath 1.0 compatibility
			 mode.</term>
                           <phrase role="xquery">This
			 component must be set by all host languages
			 that include XPath 3.1  as a subset,
			 indicating whether rules for compatibility
			 with XPath 1.0 are in effect.
			 XQuery sets the value of this component to
			 <code nobreak="false">false</code>.
                         </phrase>
                        </termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-static-namespaces" term="statically known namespaces">
                           <term>Statically known namespaces.</term> 
        This is a mapping from prefix to namespace URI that defines all the namespaces 
        that are known during static processing of a given expression.</termdef>
                     </p>
                     <p>The URI value is whitespace normalized according to the rules for the
                     <code nobreak="false">xs:anyURI</code> type in <xspecref spec="XS1-2" ref="anyURI"/> or 
                     <xspecref spec="XS11-2" ref="anyURI"/>.</p>
                     <p role="xquery">The statically known namespaces may include a binding for the zero-length prefix:
                  however, this is used only by the <termref def="dt-constructed-element-namespace-rule"/>.</p>
                     <p>Note the difference between <termref def="dt-in-scope-namespaces">in-scope namespaces</termref>, which is a dynamic property of an element node, and <termref def="dt-static-namespaces">statically known namespaces</termref>, which is a static property of an expression.</p>
                     <p role="xquery">Some namespaces are predeclared (see <specref ref="id-namespaces-and-qnames"/>); 
                     additional  namespaces can be added to the statically known namespaces by <termref def="dt-namespace-declaration">namespace declarations</termref>,
<termref def="dt-schema-import">schema imports</termref>, or  <termref def="dt-module-import">module imports</termref> in a <termref def="dt-prolog">Prolog</termref>, by  a <termref def="dt-module-declaration">module declaration</termref>, 
and by <termref def="dt-namespace-decl-attr">namespace declaration attributes</termref> in <termref def="dt-direct-elem-const">direct element constructors</termref>.</p>
                  </item>
                  <item>
                     <p diff="chg" at="A">
                        <termdef id="dt-default-namespace-elements-and-types"
                                 term="default namespace for elements and types">
                           <term>Default namespace for elements and types.</term> This is either a
				namespace URI, or the special value <code nobreak="false">"##any"</code>, or <xtermref spec="DM40" ref="dt-absent"/>. This indicates how unprefixed QNames are interpreted when
                        they appear in a position  where an element name or type name is expected.</termdef>
                     </p>
                     <ulist>
                        <item>
                           <p diff="chg" at="issue372">If the value is set to a namespace URI, 
                        this namespace is used for any such unprefixed QName. The URI value is
               whitespace-normalized according to the rules for the <code nobreak="false">xs:anyURI</code> type in <xspecref spec="XS1-2" ref="anyURI"/> or <xspecref spec="XS11-2" ref="anyURI"/>.</p>
                        </item>
                        <item>
                           <p>The special value <code nobreak="false">"##any"</code> indicates that:</p>
                           <ulist>
                              <item>
                                 <p>When an unprefixed QName is used as a <termref def="dt-name-test"/> for selecting
                              named elements in an <termref def="dt-axis-step"/>, the <termref def="dt-name-test"/>
                           will match an element having the specified local name, in any namespace or none.</p>
                              </item>
                              <item>
                                 <p>When an unprefixed QName is used in a context where a type name is expected
                           (but not as a function name), the default namespace is the <code nobreak="false">xs</code>
                           namespace, <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>.</p>
                              </item>
                              <item>
                                 <p>In any other context, an unprefixed QName represents a name in no namespace.</p>
                              </item>
                           </ulist>
                        </item>
                        <item>
                           <p diff="chg" at="issue372">If the value is <xtermref spec="DM40" ref="dt-absent"/>,
                        an unprefixed QName representing an element or type
                        name is interpreted as being in no namespace.</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-default-function-namespace" term="default function namespace">
                           <term>Default function namespace.</term> This determines how unprefixed lexical QNames
                        appearing in a <termref def="dt-static-function-call"/> or a
                        <termref def="dt-named-function-ref"/> are interpreted.</termdef>
                     </p>
                     <p>There are three possible settings:</p>
                     <olist>
                        <item>
                           <p>The property may be <xtermref spec="DM40" ref="dt-absent"/>. In this case
                     an unprefixed <termref def="dt-qname"/> appearing in a <termref def="dt-static-function-call"/> 
                      or in a <termref def="dt-named-function-ref"/>
                     is resolved first by searching the static context for a <termref def="dt-function-definition"/> in no namespace,
                     having a matching local name and <termref def="dt-arity-range"/>; if that fails to find a matching function
                     definition, a second search is conducted looking for a <termref def="dt-function-definition"/>
                     in the namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, again
                     having a matching local name and <termref def="dt-arity-range"/>.</p>
                        </item>
                        <item>
                           <p>The property may be set to the empty URI, <code nobreak="false">""</code>. In this case
                     an unprefixed <termref def="dt-qname"/> appearing in a 
                        <termref def="dt-static-function-call"/> or a <termref def="dt-named-function-ref"/>
                     is resolved by searching the static context for a <termref def="dt-function-definition"/> in no namespace,
                     having a matching local name and <termref def="dt-arity-range"/>.</p>
                        </item>
                        <item>
                           <p>The property may be set to an explicit URI, say <var>NS</var>. In this case
                     an unprefixed <termref def="dt-qname"/> appearing in a 
                        <termref def="dt-static-function-call"/> or a <termref def="dt-named-function-ref"/>
                     is resolved by searching the static context for a <termref def="dt-function-definition"/> in namespace <var>NS</var>,
                     having a matching local name and <termref def="dt-arity-range"/>.</p>
                        </item>
                     </olist>
                     <p>The URI value is whitespace-normalized according
                     to the rules for the <code nobreak="false">xs:anyURI</code> type in <xspecref spec="XS1-2" ref="anyURI"/> or <xspecref spec="XS11-2" ref="anyURI"/>
                     </p>
                     <p>Host languages may use a more complex algorithm for resolving function names. For
                     example XSLT resolves ambiguities using the concept of import precedence.
                  </p>
                     <p role="xquery">
                     In XQuery, a default function namespace can be
                     declared in the prolog in a <term>default function namespace declaration</term>
                     (see <specref ref="id-default-namespace"/>); in the absence of such a declaration, the namespace
                     <code nobreak="false">http://www.w3.org/2005/xpath-functions</code> is used.</p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-issd" term="in-scope schema definitions">
                           <term>In-scope schema
			 definitions</term> is a generic term
			 for all the element declarations, attribute declarations, and schema type
			 definitions that are in scope during
			 static analysis of an expression.</termdef> It includes the
			 following three
			 parts:</p>
                     <ulist>
                        <item>
                           <p>
                              <termdef id="dt-is-types" term="in-scope schema type">
                                 <term>In-scope schema types.</term> Each schema type
			        definition is identified either by an <termref def="dt-expanded-qname">expanded
			        QName</termref> (for a <term>named type</term>)
			        or by an <termref def="dt-implementation-dependent">implementation-dependent</termref> type
			        identifier (for an <term>anonymous
			        type</term>). The in-scope schema types include the predefined schema types described in <specref ref="id-predefined-types"/>.

                                <phrase role="xquery">If the
                                <termref def="dt-schema-aware-feature">Schema Aware Feature</termref>
                                is supported, in-scope schema types
                                also include all type definitions
                                found in imported schemas.</phrase>
                              </termdef>
                           </p>
                        </item>
                        <item>
                           <p>
                              <termdef id="dt-is-elems" term="in-scope element declarations">
                                 <term>In-scope element declarations.</term> Each element
declaration is identified either by an <termref def="dt-expanded-qname">expanded QName</termref> (for a top-level element
declaration) or by an <termref def="dt-implementation-dependent">implementation-dependent</termref> element identifier (for a
local element declaration). <phrase role="xquery"> If the
<termref def="dt-schema-aware-feature">Schema Aware Feature</termref>
is supported, in-scope element declarations include all element
declarations found in imported schemas. </phrase>
                              </termdef> An element
declaration includes information about the element’s <termref def="dt-substitution-group">substitution group</termref> affiliation.</p>
                           <p>
                              <termdef term="substitution group" id="dt-substitution-group">
                                 <term>Substitution groups</term> are defined in <xspecref spec="XS1-1" ref="Element_Equivalence_Class"/> and 
<xspecref spec="XS11-1" ref="Element_Equivalence_Class"/>. Informally, the substitution group headed by a given element (called the <term>head element</term>) consists of  the set of elements that can be substituted for the head element without affecting the outcome of schema validation.</termdef>
                           </p>
                        </item>
                        <item>
                           <p>
                              <termdef id="dt-is-attrs" term="in-scope attribute declarations">
                                 <term>In-scope attribute
declarations.</term> Each attribute declaration is identified either
by an <termref def="dt-expanded-qname">expanded QName</termref> (for a top-level attribute declaration) or by an
<termref def="dt-implementation-dependent">implementation-dependent</termref> attribute identifier (for a local attribute
declaration).  <phrase role="xquery">If the
<termref def="dt-schema-aware-feature">Schema Aware Feature</termref>
is supported, in-scope attribute declarations include all attribute
declarations found in imported
schemas.</phrase>
                              </termdef>
                           </p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-in-scope-variables" term="in-scope variables">
                           <term>In-scope variables.</term> 
                           This is a mapping from <termref def="dt-expanded-qname">expanded QNames</termref> to sequence types. It defines the
                           set of variables that are available for reference within an
                           expression. The <termref def="dt-expanded-qname">expanded QName</termref> is the name of the variable, and the type is the
                           <termref def="dt-static-type">static type</termref> of the
                           variable.</termdef>
                     </p>
                     <p>
                        <phrase role="xquery">Variable declarations in a <termref def="dt-prolog">Prolog</termref> are added to <termref def="dt-in-scope-variables">in-scope variables</termref>.</phrase>
An expression that binds a variable extends the <termref def="dt-in-scope-variables">in-scope variables</termref>, within the scope of the variable, with the variable and its type. 
Within the body of an
<termref def="dt-inline-func">inline function expression</termref>
                        <phrase role="xquery"> or <termref def="dt-udf">user-defined function</termref>
                        </phrase>, the
<termref def="dt-in-scope-variables">in-scope variables</termref> are extended
by the names and types of the <term>function
parameters</term>.</p>
                     <p role="xquery">The static type of a variable may either be declared in a query or
inferred by static type inference as discussed in  <specref ref="id-static-analysis"/>.</p>
                  </item>
                  <item diff="add" at="A">
                     <p>
                        <termdef id="dt-in-scope-named-item-types" term="in-scope named item types">
                           <term>In-scope named item types.</term> This is a mapping from 
                        <termref def="dt-expanded-qname">expanded QNames</termref> to 
                        <termref def="dt-named-item-type">named item types</termref>.</termdef>
                     </p>
                     <p>
                        <termdef id="dt-named-item-type" term="named item type">A <term>named item type</term>
                      is an <code nobreak="false">ItemType</code> identified by an <termref def="dt-expanded-qname"/>.</termdef>
                     </p>
                     <p>Named item types serve two purposes:</p>
                     <ulist>
                        <item>
                           <p>They allow frequently used item types, especially complex item types such as
                        record types, to be given simple names, to avoid repeating the definition 
                        every time it is used.</p>
                        </item>
                        <item>
                           <p>They allow the definition of recursive types, which are useful for
                     describing recursive data structures such as lists and trees. For details see
                     <specref ref="id-recursive-record-tests"/>. </p>
                        </item>
                     </ulist>
                     <p>Certain named item types (typically item types used in the signatures of built-in functions)
                  are always available in the static context. These are defined in <xspecref spec="FO40" ref="id-built-in-named-record-types"/>.</p>
                     <note>
                        <p role="xquery">In XQuery, named item types can be declared in the Query Prolog.</p>
                     </note>
                  </item>
                  <item diff="chg" at="variadicity">
                     <p>
                        <termdef id="dt-statically-known-function-definitions"
                                 term="statically known function definitions">
                           <term>Statically known function definitions.</term> This is a set of 
                           <termref def="dt-function-definition">function definitions</termref>.</termdef>
                     </p>
                     <p>Function definitions are described in <specref ref="id-function-definitions"/>.</p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-static-collations" term="statically known collations">
                           <term>Statically known collations.</term> This is an <termref def="dt-implementation-defined">implementation-defined</termref>
        mapping from URI to collation. It defines the names of the collations that are available for
				use in processing <phrase role="xquery">queries and</phrase> expressions.</termdef>
                        <termdef term="collation" id="dt-collation">A <term>collation</term> is a specification of the manner in which strings and URIs are compared and, by extension, ordered. For a more complete definition of collation, see <xspecref spec="FO40" ref="string-compare"/>.</termdef>
                     </p>
                  </item>
                  <item role="xquery">
                     <p>
                        <termdef id="dt-construction-mode" term="construction mode">
                           <term>Construction mode.</term> The
			 construction mode governs the behavior of element and document node constructors. If construction mode is <code nobreak="false">preserve</code>, the type of a constructed element node is <code nobreak="false">xs:anyType</code>, and all attribute and element nodes copied during node construction    retain their original types. If construction mode is <code nobreak="false">strip</code>, the type of a constructed element node is <code nobreak="false">xs:untyped</code>; all element nodes copied during node construction receive the type <code nobreak="false">xs:untyped</code>, and all attribute nodes copied during node construction receive the type <code nobreak="false">xs:untypedAtomic</code>.</termdef>
                     </p>
                  </item>
                  <item role="xquery">
                     <p>
                        <termdef id="dt-default-empty-order" term="default order for empty sequences">
                           <term>Default order for empty sequences.</term> This component controls the processing of empty sequences and <code nobreak="false">NaN</code> values as ordering keys in an <code nobreak="false">order by</code> clause in a FLWOR expression, as described in <specref ref="id-order-by-clause"/>.</termdef>  Its value may be <code nobreak="false">greatest</code> or <code nobreak="false">least</code>.</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <termdef id="dt-boundary-space-policy" term="boundary-space policy">
                           <term>Boundary-space
			 policy.</term> This component controls the processing of <termref def="dt-boundary-whitespace">boundary whitespace</termref>
			 by <termref def="dt-direct-elem-const">direct element constructors</termref>, as described in <specref ref="id-whitespace"/>.</termdef> Its value may be <code nobreak="false">preserve</code> or <code nobreak="false">strip</code>.</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <termdef id="dt-copy-namespaces-mode" term="copy-namespaces mode">
                           <term>Copy-namespaces mode.</term> This component controls the <termref def="dt-in-scope-namespaces"/>
                        property that
is assigned when an existing element node is copied by an element
constructor, as described in <specref ref="id-element-constructor"/>. Its value consists of two parts: <code nobreak="false">preserve</code> or <code nobreak="false">no-preserve</code>, and <code nobreak="false">inherit</code> or <code nobreak="false">no-inherit</code>.</termdef>
                     </p>
                  </item>
                  <item>
                     <p diff="chg" at="2023-05-19">
                        <termdef id="dt-static-base-uri" term="Static Base URI">
                           <term>Static Base URI.</term>
        This is an absolute URI, used to resolve relative URIs during static analysis.
                     </termdef>
                     For example, it is used to resolve module location URIs in XQuery, and 
                     the URIs in <code nobreak="false">xsl:import</code> and <code nobreak="false">xsl:include</code> in XSLT.
                     <phrase role="xquery">
        All expressions within a module have the same static base URI.
        The Static Base URI can be set using a <termref def="dt-base-uri-decl">base URI declaration</termref>.
      </phrase>
                     </p>
                     <p>
                        <phrase diff="del" at="2023-05-19">The Static Base URI is available during dynamic evaluation by use of the 
      <function>fn:static-base-uri</function> function, and is used implicitly during dynamic 
      evaluation by functions such as <function>fn:doc</function>. </phrase>Relative URI references are 
      resolved as described in <specref ref="id-resolve-relative-uri"/>.</p>
                     <p diff="add" at="2023-05-19">At execution time,
                  relative URIs supplied to functions such as <function>fn:doc</function>
                  are resolved against the <termref def="dt-executable-base-uri"/>,
                  which may or may not be the same as the Static Base URI.</p>
                     <p role="xquery" diff="del" at="2023-05-19">
      If the value of the Static Base URI is based on the location of the 
      query module (in the terminology of <bibref ref="RFC3986"/>, the URI used to retrieve 
      the encapsulating entity), then the implementation <rfc2119>may</rfc2119> use 
      different values for the Static Base URI during static analysis and 
      during dynamic evaluation. This might be necessary, for example, if a 
      query consisting of several modules is compiled, and the resulting 
      object code is distributed to a different location for execution. It 
      would then be inappropriate to use the same location when resolving 
      <code nobreak="false">import module</code> declarations as when retrieving source 
      documents using the <function>fn:doc</function> function. If an implementation uses different 
      values for the Static Base URI during static analysis and during dynamic 
      evaluation, then it is implementation-defined which of the two values is 
      used for particular operations that rely on the Static Base URI; for 
      example, it is implementation-defined which value is used for resolving 
      collation URIs.</p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-static-decimal-formats" term="statically known decimal formats">
                           <term>Statically known decimal
		      formats.</term> This is a mapping from QNames to decimal formats, with one default format that has no visible name,
		      referred to as the unnamed decimal format. Each
		      format is available for use when formatting numbers using the <function>fn:format-number</function> function.</termdef>
                     </p>
                     <p>Decimal formats are described in <specref ref="id-decimal-formats"/>.</p>
                  </item>
               </ulist>
               <div4 id="id-function-definitions">
                  <head>Function Definitions</head>
                  <p>
                     <termdef id="dt-function-definition" term="function definition">A <term>function definition</term>
                  contains information used to evaluate a static function call, including the name, parameters,
                  and return type of the function.</termdef>
                  </p>
                  <p>The properties of a <termref def="dt-function-definition"/> include:</p>
                  <ulist>
                     <item>
                        <p>The function name, which is an <termref def="dt-expanded-qname"/>.</p>
                     </item>
                     <item>
                        <p>Parameter definitions, specifically:</p>
                        <ulist>
                           <item>
                              <p>A (possibly empty) list of required parameters, each having:</p>
                              <ulist>
                                 <item>
                                    <p>a parameter name (an <termref def="dt-expanded-qname"/>)</p>
                                 </item>
                                 <item>
                                    <p>a required type (a <termref def="dt-sequence-type"/>)</p>
                                 </item>
                              </ulist>
                           </item>
                           <item>
                              <p>A (possibly empty) list of optional parameters, each having:</p>
                              <ulist>
                                 <item>
                                    <p>a parameter name (an <termref def="dt-expanded-qname"/>)</p>
                                 </item>
                                 <item>
                                    <p>a required type (a <termref def="dt-sequence-type"/>)</p>
                                 </item>
                                 <item>
                                    <p>a default value expression (an <term>expression</term>: see <specref ref="id-expressions"/>)</p>
                                 </item>
                              </ulist>
                           </item>
                        </ulist>
                        <p>The names of the parameters must be distinct.</p>
                        <p>
                           <termdef id="dt-arity-range" term="arity range">A <termref def="dt-function-definition"/> has an <term>arity range</term>,
                        which is a range of consecutive non-negative integers. If the function definition has <var>M</var> required parameters
                        and <var>N</var> optional parameters, then its arity range is from <var>M</var> to <var>M</var>+<var>N</var>
                        inclusive.</termdef>
                        </p>
                        <!--<p><termdef id="dt-variadic" term="variadic">A <termref def="dt-function-definition"/> may
                     be declared to be <term>variadic</term>. In a static call of a variadic function, multiple
                     arguments may be mapped to a single parameter in the function definition. In a variadic
                     function with <var>M</var> declared parameters, the arity range is from <var>M-1</var>
                     to positive infinity.</termdef></p>
                     
                     <p>For an overview of variadic functions, see <specref ref="id-variadic-functions-overview"/>.</p>
                     
                     <note><p>Examples of system functions defined to be variadic are <function>fn:concat</function>
                     and <function>fn:codepoints-to-string</function>. User-written functions in XQuery may
                     be declared as variadic by using the <code>%variadic</code> annotation; the equivalent
                     in XSLT is to use the attribute <code>xsl:function/@variadic = "yes"</code>.</p></note>
                     
                   -->
                        <p>The static context may contain several <termref def="dt-function-definition">function definitions</termref> with the
                        same name, but the <termref def="dt-arity-range">arity ranges</termref> of two such function definitions must not 
                        overlap. For example, if two function definitions <var>A</var> and <var>B</var> have the same function name, then:</p>
                        <ulist>
                           <item>
                              <p>It is acceptable for <var>A</var> to have two required parameters and no optional
                           parameters, while <var>B</var> has three required parameters and one optional
                           parameter.</p>
                           </item>
                           <item>
                              <p>It is not acceptable for <var>A</var> to have one required parameter while <var>B</var>
                           has three optional parameters.</p>
                           </item>
                           <!--<item><p>It is not possible for both <var>A</var> and <var>B</var> to be <termref def="dt-variadic"/>.</p></item>-->
                        </ulist>
                        <note>
                           <p>Implementations must ensure that no two <termref def="dt-function-definition">function definitions</termref> 
                        have the same <termref def="dt-expanded-qname">expanded QName</termref> and overlapping
                        arity ranges (even if the signatures are consistent).</p>
                           <p>XQuery and XSLT enforce this rule by defining a static error if the rule is violated; but further constraints
                           may be needed if an API allows external functions to be added to the static context.</p>
                        </note>
                     </item>
                     <item>
                        <p>A return type (a <termref def="dt-sequence-type"/>)</p>
                     </item>
                     <item>
                        <p diff="add" at="2023-03-11">The function category, which is one of application, system, or external:</p>
                        <ulist diff="add" at="2023-03-11">
                           <item>
                              <p>
                                 <termdef id="dt-application-function" term="application function">
                                    <term>Application functions</term> are function definitions written in a 
                           host language such as XQuery or XSLT whose syntax and
                           semantics are defined in this family of specifications. Their behavior 
                           (including the rules determining the static and dynamic context) follows the
                           rules for such functions in the relevant host language specification.</termdef>
                           The most common application functions are functions written by users in XQuery or XSLT.
                        </p>
                           </item>
                           <item>
                              <p>
                                 <termdef id="dt-system-function" term="system function">
                                    <term>System functions</term> include the functions defined in <bibref ref="xpath-functions-40"/>, functions defined by the specifications 
                           of a host language, <termref def="dt-constructor-function">constructor functions</termref> 
                           for atomic types, and any additional functions provided
                           by the implementation. System functions are sometimes called built-in
                           functions.</termdef>
                              </p>
                              <p>The behavior of system functions follows the rules given for the individual
                              function in this family of specifications, or in the specification of the
                              particular processor implementation. A system function may have behavior that depends on the
                              static or dynamic context of the caller (for example, comparing strings
                              using the default collation from the <phrase diff="chg" at="2023-05-19">dynamic</phrase> context of the caller). Such
                              functions are said to be <termref def="dt-context-dependent"/>.</p>
                           </item>
                           <item>
                              <p>
                                 <termdef id="dt-external-function" term="external function">
                                    <term>External functions</term> 
                           can be characterized as functions that are neither
                           part of the processor implementation, nor written in a language whose semantics
                           are under the control of this family of specifications. The semantics of external
                           functions, including any context dependencies, are entirely implementation-defined. 
                           In XSLT, external functions are called 
                           <xspecref spec="XT30" ref="extension-functions">extension functions</xspecref>. </termdef>
                              </p>
                              <p>For example, an implementation might provide a mechanism allowing
                              external functions to be written in a language such as Java or Python.
                              The way in which argument and return values are converted between
                              the XDM type system and the type system of the external language is
                              implementation-defined.
                           </p>
                           </item>
                        </ulist>
                        <p diff="add" at="2023-03-11">
                           <termdef id="dt-context-dependent" term="context dependent">A 
                        <termref def="dt-function-definition"/> is said to be <term>context dependent</term>
                        if its result depends on the static or dynamic context of its caller.
                        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>
                        <note diff="add" at="2023-03-11">
                           <p>Some system functions, such as <function>fn:position</function>, <function>fn:last</function>,
                        and <function>fn:static-base-uri</function>, exist for the sole purpose of providing information
                        about the static or dynamic context of their caller.</p>
                        </note>
                        <note>
                           <p diff="add" at="2023-03-11">
                              <termref def="dt-application-function">Application functions</termref> 
                        are context dependent only to the extent that they define optional parameters with default
                        values that are context dependent.</p>
                        </note>
                     </item>
                     <item>
                        <p>A (possibly empty) set of <term>function annotations</term>
                        </p>
                        <p role="xquery">In XQuery, function annotations are described in <specref ref="id-annotations"/>.</p>
                     </item>
                     <item>
                        <p diff="chg" at="2023-03-11">A body. The function 
                     body contains the logic that enables the function
                     result to be computed from the supplied arguments and information in the static and dynamic context.</p>
                     </item>
                  </ulist>
                  <!--<p diff="add" at="B"><termref def="dt-system-function">System functions</termref>
                  (also commonly called built-in functions) are <termref def="dt-function-definition">function definitions</termref> that are always
                  present in the static context by virtue of rules in the host language; they will typically include
                  the functions specified in <bibref ref="xpath-functions-40"/>.</p>
               
               -->
                  <p>The <termref def="dt-function-definition">function definitions</termref> 
                  present in the static context are available for reference from a 
                  <termref def="dt-static-function-call">static function call</termref>,
                  or from a 
                  <termref def="dt-named-function-ref">named function reference</termref>.
                  
               </p>
               </div4>
               <div4 id="id-decimal-formats">
                  <head>Decimal Formats</head>
                  <changes>
                     <change issue="1048" PR="1250" date="2024-06-03">
                           Several decimal format properties, including minus sign, exponent separator, percent, and per-mille,
                           can now be rendered as arbitrary strings rather than being confined to a single
                           character.
                        </change>
                  </changes>
                  <p>Each decimal format defines a set of properties, which control the interpretation of characters
                        in the picture string supplied to the <function>fn:format-number</function>
                        function, and also specify characters to be used in the result
                        of formatting the number.</p>
                  <p>Each property potentially has two parts: a marker character <var>M</var> used
                     in the picture string to mark an insertion position, and a rendition string <var>R</var>
                     to indicate how the relevant property is to be rendered in the output of the 
                     <code nobreak="false">fn:format-number</code> function. In the list below properties are annotated
                     with <emph>(<var>M</var>)</emph>, <emph>(<var>R</var>)</emph>, or 
                     <emph>(<var>M</var>, <var>R</var>)</emph> to indicate whether the property includes a
                     marker character, a rendition string, or both.</p>
                  <p>In XQuery and XSLT declarations
                     defining the values of properties, a property where the marker character and the
                     rendition differ is indicated using the syntax <code nobreak="false">
                        <var>M</var>:<var>R</var>
                     </code>. For
                     example the <code nobreak="false">percent</code> property may be expressed as <code nobreak="false">%:pc</code>
                     to indicate that the character <code nobreak="false">%</code> will be used in the picture string,
                     and the string <code nobreak="false">pc</code> will be used in the function output.
                     In this example, the value <code nobreak="false">0.10</code>, formatted with the picture string 
                      <code nobreak="false">#0%</code>, results in the output <code nobreak="false">10pc</code>
                  </p>
                  <ulist>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-decimal-separator"
                                    term="decimal-separator">
                              <term>decimal-separator</term>
                              <emph>(<var>M</var>, <var>R</var>)</emph> is
                                 used to separate the integer part of the number from the fractional part.
                                 The default value for both the marker and the rendition is <char>U+002E</char>.</termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-exponent-separator"
                                    term="exponent-separator">
                              <term>exponent-separator</term>
                              <emph>(<var>M</var>, <var>R</var>)</emph> is
                                 used to separate the mantissa from the exponent in
                                 scientific notation. The default value 
                                 for both the marker and the rendition is <char>U+0065</char>.</termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-grouping-separator"
                                    term="grouping-separator">
                              <term>grouping-separator</term>
                              <emph>(<var>M</var>, <var>R</var>)</emph> is used to 
                                 separate groups of digits (for example as a thousands separator).
                                 The default value for both the marker and the rendition is <char>U+002C</char>.</termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-percent" term="percent">
                              <term>percent</term>
                              <emph>(<var>M</var>, <var>R</var>)</emph> is used to 
                                 indicate that the number is written as a per-hundred fraction; the default
                                 value for both the marker and the rendition is <char>U+0025</char>.</termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-per-mille" term="per-mille">
                              <term>per-mille</term>
                              <emph>(<var>M</var>, <var>R</var>)</emph> is used to 
                                 indicate that the number is written as a per-thousand fraction; the default
                                 value for both the marker and the rendition is <char>U+2030</char>.</termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-zero-digit" term="zero-digit">
                              <term>zero-digit</term>
                              <emph>(<var>M</var>)</emph>
                                 is the character used in the picture string to represent the digit zero; the default
                                 value is <char>U+0030</char>. This character must be a digit
                                 (category Nd in the Unicode property database), and it must have
                                 the numeric value zero. This property implicitly defines the
                                 ten Unicode characters that are used to represent the values 0
                                 to 9 in the function output: Unicode is organized so that each
                                 set of decimal digits forms a contiguous block of characters in
                                 numerical sequence. Within the picture string any of these ten character 
                                 can be used (interchangeably) as a place-holder for a mandatory digit.
                                 Within the final result string, these ten characters are used to represent
                                 the digits zero to nine.</termdef>
                        </p>
                     </item>
                     <!--</ulist>
                     
                     <p>In the case of the properties <termref def="id-static-decimal-format-decimal-separator"/>,
                     <termref def="id-static-decimal-format-grouping-separator"/>,
                     <termref def="id-static-decimal-format-exponent-separator"/>,
                        <termref def="id-static-decimal-format-percent"/>
                        and <termref def="id-static-decimal-format-per-mille"/>, the property may take the form
                        <code>m:r</code>, where <code>m</code> is a single-character marker used in the picture
                        string to indicate where the relevant output should appear, and <code>r</code> is the
                        string used to represent the property in the result. .
                     </p>
                     
                     <p>The following properties specify 
                        characters to be used in the picture string supplied to the <function>fn:format-number</function>
                        function, but not in the formatted number. In each case the value must be a single character.
                     </p>
                     
                     <ulist>-->
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-digit" term="digit">
                              <term>digit</term>
                              <emph>(<var>M</var>)</emph>
                                 is a character used in the picture string to represent an optional digit; 
                                 the default value is <char>U+0023</char>.</termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-pattern-separator"
                                    term="pattern-separator">
                              <term>pattern-separator</term>
                              <emph>(<var>M</var>)</emph> is a character used
                                 to separate positive and negative sub-pictures
                                 in a picture string; the default value is <char>U+003B</char>.</termdef>
                        </p>
                     </item>
                     <!--                    </ulist>
                     
                     <p>The following properties specify characters or strings that
                        may appear in the result of formatting the number, but not in the picture string:</p>
                     
                     <ulist>-->
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-infinity" term="infinity">
                              <term>infinity</term>
                              <emph>(<var>R</var>)</emph>
                                 is the string used to represent the double value infinity (<code nobreak="false">INF</code>); the
                                 default value is the string <code nobreak="false">"Infinity"</code>
                           </termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-NaN" term="NaN">
                              <term>NaN</term>
                              <emph>(<var>R</var>)</emph>
                                 is the string used to
                                 represent the double value <code nobreak="false">NaN</code> (not a number); the default value is the string <code nobreak="false">"NaN"</code>
                           </termdef>
                        </p>
                     </item>
                     <item>
                        <p>
                           <termdef id="id-static-decimal-format-minus-sign" term="minus-sign">
                              <term>minus-sign</term>
                              <emph>(<var>R</var>)</emph> is the string used to mark negative numbers; the
                                 default value is <char>U+002D</char>.</termdef>
                        </p>
                     </item>
                  </ulist>
               </div4>
            </div3>
            <div3 id="eval_context">
               <head>Dynamic Context</head>
               <changes>
                  <change issue="129" PR="368" date="2023-09-14">
                  The concept of the context item has been generalized, so it is now a context value. That is,
                  it is no longer constrained to be a single item.
               </change>
                  <change issue="1161" PR="1265" date="2024-06-11">
                  The rules regarding the <code nobreak="false">document-uri</code> property of nodes returned by the
                  <function>fn:collection</function> function have been relaxed.
               </change>
               </changes>
               <p>
                  <termdef id="dt-dynamic-context" term="dynamic context">The <term>dynamic
context</term> of an expression is defined as information that is needed for the dynamic evaluation of an expression,
                  beyond any information that is needed from the <termref def="dt-static-context"/>.</termdef> If
evaluation of an expression relies on some part of the <termref def="dt-dynamic-context"/> that 
is <xtermref spec="DM40" ref="dt-absent"/>, a <termref def="dt-type-error"/> 
               is raised <errorref class="DY" code="0002"/>.</p>
               <note>
                  <p>In previous versions of the specification, this was classified as a
            <termref def="dt-dynamic-error"/>. The change allows the error to be raised during
            static analysis when possible; for example a function written as
            <code nobreak="false">fn($x) { @code }</code> can now be reported as an error whether or not
            the function is actually evaluated. The actual error code remains unchanged
            for backwards compatibility reasons.</p>
                  <p>There are other cases where static detection of the error is not possible.</p>
               </note>
               <p>The individual
components of the <termref def="dt-dynamic-context">dynamic context</termref> are described below.</p>
               <p>In general, the dynamic context for the outermost expression is supplied externally,
               often by some kind of application programming interface (API) allowing XQuery 4.0
               expressions to be invoked from a host language. Application Programming Interfaces
               are outside the scope of this specification. <phrase role="xquery">In XQuery 4.0,
               some aspects of the dynamic context (for example, initial values of variables)
               are defined within the query prolog.</phrase> The dynamic context for inner subexpressions
               may be set by their containing expressions: for example in a mapping expression 
               <code nobreak="false">
                     <var>E1</var>!<var>E2</var>
                  </code>,
               the value of the <termref def="dt-focus"/> (part of the dynamic context) for evaluation
               of <var>E2</var> is defined by the evaluation of <var>E1</var>.</p>
               <p>Some aspects of the dynamic context are outside the direct control of the query author;
               they are defined by the implementation, which may or may not allow them to be configured by users.
               An example is <termref def="dt-available-docs"/>, which is an abstraction for the set of XML
               documents that can be retrieved by URI from within an expression. In some environments this may be
               the entire contents of the web; in others it may be constrained to documents that satisfy
               particular security constraints; and in some environments the set of available documents
               might even be empty. These components of the dynamic context are generally treated as being constant for
               the duration of the execution.</p>
               <p>
                  <phrase role="xquery">Rules governing the initialization and alteration of  these components can be found in  <specref ref="id-xq-evaluation-context-components" role="xquery"/>.</phrase>
               </p>
               <p>The components of the 
           <termref def="dt-dynamic-context"/> are listed below.</p>
               <p>
                  <termdef id="dt-focus" term="focus">The first three components of
the <termref def="dt-dynamic-context">dynamic context</termref>
(context value, context position, and context size) are called the
<term>focus</term> of the expression. </termdef> The focus enables the
processor to keep track of which items are being processed by the
expression.

<phrase role="xquery">If any component in the focus is defined, all components of the focus are defined.</phrase>
               </p>
               <p>
                  <termdef id="dt-fixed-focus" term="fixed focus">A <term>fixed focus</term> is a focus for an expression that is evaluated once, 
                  rather than being applied to a series of values; in a fixed focus, 
                  the context value is set to one specific value, the context position is 1, and the context size is 1.</termdef>
               </p>
               <p>
                  <termdef id="dt-singleton-focus" term="singleton focus">A <term>singleton focus</term> is a <termref def="dt-fixed-focus"/> in which the
                  <termref def="dt-context-value"/> is a <termref def="dt-singleton"/> item.</termdef>.
               With a singleton focus, the context value is a single item, the context position is 1, and the context size is 1.
               </p>
               <p>Certain language constructs, notably the <termref def="dt-path-expression">path operator</termref>
                  <code role="parse-test" nobreak="false">
                     <var>E1</var>/<var>E2</var>
                  </code>, the <nt def="doc-xquery40-SimpleMapExpr">simple map operator<!--$spec = xquery40--></nt>
                  <code role="parse-test" nobreak="false">
                     <var>E1</var>!<var>E2</var>
                  </code>, and the <termref def="dt-predicate">predicate</termref>
                  <code role="parse-test" nobreak="false">
                     <var>E1</var>[<var>E2</var>]</code>, create a new focus
for the evaluation of a sub-expression. In these constructs, <var role="parse-test">E2</var> is evaluated once for each item in the
sequence that results from evaluating <var role="parse-test">E1</var>. Each time <var role="parse-test">E2</var> is evaluated, it is evaluated with a
different focus. The focus for evaluating <var role="parse-test">E2</var> is referred to below as the <term>inner
focus</term>, while the focus for evaluating <var role="parse-test">E1</var> is referred to as the <term>outer
focus</term>. The inner focus is used only for the evaluation of <var role="parse-test">E2</var>. Evaluation of <var>E1</var> continues with its original focus unchanged.</p>
               <ulist>
                  <item>
                     <p>
                        <termdef id="dt-context-value" term="context value">The <term>context value</term>
is the <termref def="dt-value">value</termref> currently being processed.</termdef>
                     In many cases (but not always), the context value will be a single item.
                     <termdef id="dt-context-node" term="context node">When the context value is a single item, it can also be referred
                        to as the <term>context item</term>; when it is a single node,
it can also be referred to as the <term>context
node</term>.</termdef> The context value is returned by an expression
consisting of a single dot (<code role="parse-test" nobreak="false">.</code>). When an expression <code role="parse-test" nobreak="false">
                           <var>E1</var>/<var>E2</var>
                        </code> or <code role="parse-test" nobreak="false">
                           <var>E1</var>[<var>E2</var>]</code> is evaluated, each item in the
sequence obtained by evaluating <code role="parse-test" nobreak="false">
                           <var>E1</var>
                        </code>
becomes the context value in the inner focus for an evaluation of <var role="parse-test">E2</var>. </p>
                     <p role="xquery">
                        <termdef id="dt-initial-context-value" term="initial context value">
    
    
      In the dynamic context of every module in a query,
      the context value component must have the same setting.
      If this shared setting is not <xtermref spec="DM40" ref="dt-absent"/>,
      it is referred to as the <term>initial context value</term>.
    
  </termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-context-position" term="context position">The <term>context
position</term> is the position of the context value within the
series of values currently being processed.</termdef> It changes whenever the context value
changes. When the focus is defined, the value of the context position is an integer greater than zero. The context
position is returned by the expression <code role="parse-test" nobreak="false">fn:position()</code>. When an expression <code role="parse-test" nobreak="false">
                           <var>E1</var>/<var>E2</var>
                        </code> or <code role="parse-test" nobreak="false">
                           <var>E1</var>[<var>E2</var>]</code> is evaluated, the context position in
the inner focus for an evaluation of <code role="parse-test" nobreak="false">E2</code>
is the position of the context value in the sequence obtained by
evaluating <var role="parse-test">E1</var>. The position of the
first item in a sequence is always 1 (one). The context position is
always less than or equal to the context size.</p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-context-size" term="context size">The <term>context
size</term> is the number of values in the series of values currently
being processed.</termdef> Its value is always an
integer greater than zero. The context size is returned by the
expression <code role="parse-test" nobreak="false">fn:last()</code>. When an expression
<code role="parse-test" nobreak="false">
                           <var>E1</var>/<var>E2</var>
                        </code> or <code role="parse-test" nobreak="false">
                           <var>E1</var>[<var>E2</var>]</code> is evaluated, the context size in the
inner focus for an evaluation of <var role="parse-test">E2</var> is
the number of items in the sequence obtained by evaluating <var role="parse-test">E1</var>. </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-variable-values" term="variable values">
                           <term>Variable values</term>. 
        This is a mapping from <termref def="dt-expanded-qname">expanded QNames</termref> to values. 
        It contains the
				same <termref def="dt-expanded-qname">expanded QNames</termref> as the <termref def="dt-in-scope-variables">in-scope variables</termref> in the
				<termref def="dt-static-context">static context</termref> for the expression. The <termref def="dt-expanded-qname">expanded QName</termref> is the name of the variable and the value is the dynamic value of the variable, which includes its <termref def="dt-dynamic-type">dynamic type</termref>.</termdef>
                     </p>
                  </item>
                  <item>
                     <p diff="chg" at="variadicity">
                        <termdef term="dynamically known function definitions"
                                 id="dt-dynamically-known-function-definitions">
                           <term>Dynamically known function definitions</term>.
        This is a set of <termref def="dt-function-definition">function definitions</termref>. It includes the
                        <termref def="dt-statically-known-function-definitions"/> as a subset, but may include
                        other function definitions that are not known statically.
      </termdef>
                     </p>
                     <p>The function definitions in the dynamic context are used primarily by the <function>fn:function-lookup</function>
                  function.</p>
                     <p>If two function definitions in the <termref def="dt-dynamically-known-function-definitions"/> have the same
                     name, then their <termref def="dt-arity-range">arity ranges</termref> must not overlap.</p>
                     <note>
                        <p>The reason for allowing named functions to be available dynamically beyond those that are
                  available statically is primarily to allow for cases where the run-time execution
                  environment is significantly different from the compile-time environment. This could happen, for example,
                  if a stylesheet or query is compiled within a web server and then executed in the web browser.
                  The <function>fn:function-lookup</function> function allows dynamic discovery of resources that were not
                  available statically.</p>
                     </note>
                     <!--                supplies a function for each signature in 
      <termref
                        def="dt-known-func-signatures"
                        >
        statically known function signatures
      </termref>
      and may supply other functions 
      (see <specref
                        ref="id-consistency-constraints"
                        />).  Named functions can include 
      
      
      <termref
                        def="dt-external-function">external functions</termref>.
      
                        id="dt-implementation-defined-function"
                        term="implementation-defined function"
                           >An <term>implementation-defined function</term> is an <termref
                           def="dt-external-function">external function</termref> that is <termref
                           def="dt-implementation-defined">implementation-defined</termref>
                     </termdef>.
        
        <phrase role="xpath">
                        <termdef id="dt-host-language-function" term="host language function"
                           role="xpath">A <term>host language function</term> is an <termref
                              def="dt-external-function"
                              >external function</termref> defined by the <termref
                              def="dt-host-language">host language</termref>.</termdef>
                     </phrase>
                  </p>-->
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-date-time" term="current dateTime">
                           <term>Current dateTime.</term> This information represents
				an <termref def="dt-implementation-dependent">implementation-dependent</termref> point in time during the processing of <phrase role="xquery">a query</phrase>
                        , and includes an explicit timezone. It can be retrieved by the  <function>fn:current-dateTime</function> function. 
                        If called multiple times during the execution of <phrase role="xquery">a query</phrase>
                        ,
				this function always returns the same result.</termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-timezone" term="implicit timezone">
                           <term>Implicit timezone.</term> This is the timezone to be used when a date,
time, or dateTime value that does not have a timezone is used in a
comparison or arithmetic operation. The implicit timezone is an  <termref def="dt-implementation-defined">implementation-defined</termref> value of type
<code nobreak="false">xs:dayTimeDuration</code>. See <xspecref spec="XS1-2" ref="dateTime-timezones"/> or
<xspecref spec="XS11-2" ref="dateTime"/> for the range of valid values of a timezone.</termdef>
                     </p>
                  </item>
                  <item diff="add" at="2023-05-19">
                     <p>
                        <termdef id="dt-executable-base-uri" term="Executable Base URI">
                           <term>Executable Base URI.</term> This is an absolute URI used
                     to resolve relative URIs during the evaluation of expressions;
                     it is used, for example, to resolve a relative URI supplied
                     to the <function>fn:doc</function> or <function>fn:unparsed-text</function>
                     functions.
                  </termdef>
                     </p>
                     <p>URIs are resolved as described in <specref ref="id-resolve-relative-uri"/>.</p>
                     <p>The function <function>fn:static-base-uri</function>, despite its name, returns the
                     value of the <termref def="dt-executable-base-uri"/>.</p>
                     <p>In many straightforward processing scenarios, the <termref def="dt-executable-base-uri"/>
                  in the dynamic context will be the same as the <termref def="dt-static-base-uri"/> for the
                     corresponding expression in the static context. There are situations, however, where they may differ:</p>
                     <ulist>
                        <item>
                           <p>Some processors may allow the static analysis of a query or stylesheet
                     to take place on a development machine, while execution of the query or stylesheet
                     happens on a test or production server. In this situation, resources needed during
                     static analysis (such as other modules of the query or stylesheet) will be located
                     on the development machine, by reference to the <termref def="dt-static-base-uri"/>,
                     while resources needed during execution (such as reference data files) will be located
                     on the production machine, accessed via the <termref def="dt-executable-base-uri"/>.</p>
                        </item>
                        <item>
                           <p>When the <function>fn:static-base-uri</function> function is called within
                     the initializing expression of an optional parameter in a function declaration,
                     it returns the executable base URI of the relevant function call. This allows a user-written
                     function to accept two parameters: a required parameter containing a relative URI, and an
                     optional parameter containing a base URI. The optional parameter can be given a default
                     value of <code nobreak="false">fn:static-base-uri()</code>, allowing the code in the function body
                     to resolve the relative URI against the executable base URI of the caller.</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-def-collation" term="default collation">
                           <term>Default
                           collation.</term> This identifies one of the collations in <termref def="dt-static-collations">statically known collations</termref> as the  collation to be
                        used by functions and operators for comparing and ordering values of type <code nobreak="false">xs:string</code> and <code nobreak="false">xs:anyURI</code> (and types derived from them) when no
                        explicit collation is
                        specified.</termdef>
                     </p>
                     <note diff="add" at="2023-05-19">
                        <p>Although the default collation is defined (in 4.0) as a property of the
                     dynamic context, its value will in nearly all cases be known statically. The reason it is defined in the
                     dynamic context is to allow a call on the <function>fn:default-collation</function> function to be used when defining
                     the default value of an optional parameter to a user-defined function. In this situation,
                     the actual value supplied for the parameter is taken from the dynamic context of the relevant function call.</p>
                     </note>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-default-language" term="default language">
                           <term>Default language.</term>
  This is the natural language used when creating human-readable output
  (for example, by the functions <function>fn:format-date</function> and <function>fn:format-integer</function>)
  if no other language is requested. 
  The value is a language code as defined by the type <code nobreak="false">xs:language</code>.</termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-default-calendar" term="default calendar">
                           <term>Default calendar.</term>
    This is the calendar used when formatting dates in human-readable output
    (for example, by the functions <function>fn:format-date</function> and <function>fn:format-dateTime</function>)
    if no other calendar is requested. 
    The value is a string.</termdef>
                     </p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-default-place" term="default place">
                           <term>Default place.</term>
    This is a geographical location used to identify the place where events happened (or will happen) when
    processing dates and times using functions such as <function>fn:format-date</function>, <function>fn:format-dateTime</function>,
     and <function>fn:civil-timezone</function>,
    if no other place is specified. It is used when translating timezone offsets to civil timezone names,
    and when using calendars where the translation from ISO dates/times to a local representation is dependent
    on geographical location. Possible representations of this information are an ISO country code or an
    Olson timezone name, but implementations are free to use other representations from which the above
    information can be derived. The only requirement is that it should uniquely identify a civil timezone,
    which means that country codes for countries with multiple timezones, such as the United States,
    are inadequate.</termdef>
                     </p>
                  </item>
                  <!--<item>
                  <p>
                     <termdef id="dt-available-docs" term="available documents">
                        <term>Available
    documents.</term> This is a mapping of strings to document nodes.  Each string
    represents the absolute URI of a resource. The document node is the root of a tree that represents that resource 
    using the <termref
                           def="dt-datamodel"
                           >data model</termref>. The document node is returned by the <function>fn:doc</function> 
    function when applied to that URI.</termdef> The set of available documents may be empty.</p>
                  <!-\-<p>If there are one or more 
    URIs in <termref def="dt-available-docs"
                        >available documents</termref> that map to a document
    node <code>D</code>, then the document-uri property of <code>D</code> must either be absent, or must
    be one of these URIs.</p>
                  <note>
                     <p>This means that given a document node <code>$N</code>, the result of
    <code
                           role="parse-test"
                           >fn:doc(fn:document-uri($N)) is $N</code> will always be <code>true</code>, unless
  <code
                           role="parse-test">fn:document-uri($N)</code> is an empty sequence.</p>
                  </note>-\->
               </item>


               <item>
                  <p>
                     <termdef id="dt-available-text-resources" term="available text resources">
                        <term>Available text resources</term>. 
  This is a mapping of strings to text resources. Each string
  represents the absolute URI of a resource. The resource is returned
  by the <function>fn:unparsed-text</function> function when applied to that
  URI.</termdef> The set of available text resources may be empty.</p>
               </item>
               
               <item>
                  <p>
                     <termdef id="dt-available-binary-resources" term="available binary resources">
                        <term>Available binary resources</term>. 
  This is a mapping of strings to binary resources. Each string
  represents the absolute URI of a resource. The resource is returned
  by the <code>fn:unparsed-binary</code> function when applied to that
  URI.</termdef> The set of available binary resources may be empty.</p>
               </item>


               <item>
                  <p>
                     <termdef id="dt-available-collections" term="available item collections">
                        <term>Available
                           collections.</term> This is a mapping of
                         strings to sequences of items. Each string
                         represents the absolute URI of a
                         resource. The sequence of items represents
                         the result of the <function>fn:collection</function>
                         function when that URI is supplied as the
                         argument. </termdef> The set of available
                            collections may be empty.</p>

                  <p>Ideally, for every document node <code>D</code> that is in the target of a 
                     mapping in <termref def="dt-available-collections"/>, or that is the root of a tree containing 
                     such a node, the document-uri property of <code>D</code> should either be absent, 
                     or should be a URI <code>U</code> such that <termref
                        def="dt-available-docs"/> contains a mapping from <code>U</code> to <code>D</code>.

</p>
                  <note>
                     <p>That is to say, the <code>document-uri</code> property of nodes returned
                        by the <function>fn:collection</function> function should be such that
                        calling <function>fn:doc</function> with that URI returns the relevant node.</p>
                     <p>It is not always possible to ensure this, especially in cases where 
                        dereferencing of document or collection URIs is configurable using
                        configuration files or user-supplied resolver code.</p>
                  </note>
               </item>
-->
                  <item>
                     <p>
                        <termdef id="dt-default-collection" term="default collection">
                           <term>Default  collection.</term>
    This is the sequence of items  that would result from calling the <function>fn:collection</function> function
    with no arguments.</termdef> The value of <term>default   collection</term> may be initialized by the
    implementation.</p>
                  </item>
                  <!--<item>
                  <p>
                     <termdef id="dt-available-uri-collections" term="available uri collections">
                        <term>Available
    URI collections.</term> This is a mapping of
    strings to sequences of URIs. The string
    represents the absolute URI of a
    resource which can be interpreted as an aggregation of a number of individual resources each of which
    has its own URI. The sequence of URIs represents
    the result of the <function>fn:uri-collection</function>
    function when that URI is supplied as the
    argument. </termdef> There is no implication that the URIs in this sequence
    can be successfully dereferenced, or that the resources they refer to have any particular media type.</p>
                  <note>
                     <p>An implementation <rfc2119>may</rfc2119> maintain some consistent relationship between the available
    collections and the available URI collections, for example by ensuring that the result of
  <code>fn:uri-collection(X)!fn:doc(.)</code> is the same as the result of <code>fn:collection(X)</code>.
    However, this is not required. The <function>fn:uri-collection</function> function is more 
    general than <function>fn:collection</function> in that <phrase diff="del" at="A">it allows access to resources other 
    than XML documents; at the same time,</phrase> <function>fn:collection</function> allows access to 
    nodes that might lack individual URIs, for example nodes corresponding 
    to XML fragments stored in the rows of a relational database.</p>
                  </note>
               </item>
-->
                  <item>
                     <p>
                        <termdef id="dt-default-uri-collection" term="default URI collection">
                           <term>Default URI collection.</term>
    This is the sequence of URIs that would result from calling the <function>fn:uri-collection</function> function
    with no arguments.</termdef> The value of <term>default URI collection</term> may be initialized by the
    implementation.</p>
                  </item>
                  <item>
                     <p>
                        <termdef id="dt-environment-variables" term="environment variables">
                           <term>Environment variables.</term>
  This is a mapping from names to values. 
    Both the names and the values are strings. The names are compared using an
    <termref def="dt-implementation-defined">implementation-defined</termref> collation, and are unique under this collation. The set of environment variables is
  <termref def="dt-implementation-defined">implementation-defined</termref> and <rfc2119>may</rfc2119> be empty.</termdef>
                     </p>
                     <note>
                        <p>A possible implementation is to provide the set of POSIX environment variables (or their equivalent on other
      operating systems) appropriate to the process in which the <phrase role="xquery">query is initiated</phrase>
                        .</p>
                     </note>
                  </item>
               </ulist>
            </div3>
         </div2>
         <div2 id="id-security-resources">
            <head>External Resources and Security</head>
            <changes>
               <change issue="2047" PR="2213" date="2025-10-23">This section 
               (<quote>External Resources and Security</quote>) is new.</change>
            </changes>
            <p>The XPath, XQuery, and XSLT languages provide a number of capabilities
         to access external resources. These include:</p>
            <ulist>
               <item>
                  <p>Functions such as <function>doc</function>, <function>doc-available</function>,
            <function>unparsed-text</function>, <function>unparsed-text-lines</function>, 
               <function>unparsed-text-available</function>, <function>collection</function>
                     <function>uri-collection</function>, and <function>unparsed-binary</function>, and in XSLT,
            the <code nobreak="false">document</code> function and the <code nobreak="false">xsl:source-document</code>
            and <code nobreak="false">xsl:merge</code> instructions.</p>
               </item>
               <item>
                  <p>Static inclusion of code using <code nobreak="false">import module</code> in XQuery,
            or <code nobreak="false">xsl:include</code>, <code nobreak="false">xsl:import</code>, and <code nobreak="false">xsl:use-package</code>
            in XSLT.</p>
               </item>
               <item>
                  <p>Dynamic inclusion and execution of external code using the functions
               <function>transform</function> and <function>load-xquery-module</function>,
            and in XSLT, the <code nobreak="false">xsl:evaluate</code> instruction.</p>
               </item>
               <item>
                  <p>The ability to write to external resources using the 
               <code nobreak="false">xsl:result-document</code> instruction in XSLT, or the <function>put</function>
            function in the XQuery Update Facility.</p>
               </item>
               <item>
                  <p>The ability to invoke arbitrary user-defined external functions (called
            extension functions in XSLT).</p>
               </item>
               <item>
                  <p>The ability to invoke vendor-defined external/extension functions;
            a notable example being the EXPath File library.</p>
               </item>
               <item>
                  <p>Access to environment variables and system properties using functions such
            as <function>environment-variable</function>, <function>available-environment-variables</function>,
            and (in XSLT) <code nobreak="false">system-property</code>.</p>
               </item>
               <item>
                  <p>Static inclusion of XSD schemas and schema documents using 
               <code nobreak="false">import schema</code>in XQuery or <code nobreak="false">xsl:import-schema</code> in XSLT,
            or indirectly using <code nobreak="false">xs:import</code>, <code nobreak="false">xs:include</code>,
            <code nobreak="false">xs:redefine</code>, or <code nobreak="false">xs:override</code> in XSD schema documents.</p>
               </item>
               <item>
                  <p>Dynamic loading of XSD schema documents (directly or indirectly) 
               using the <function>xsd-validator</function> function.</p>
               </item>
               <item>
                  <p>The ability to parse XML or HTML documents that contain references to external 
               entities, for example by using the <code nobreak="false">parse-xml</code> and <code nobreak="false">parse-html</code>
            functions.</p>
               </item>
               <item>
                  <p>The ability to parse XML documents in a way that causes other external resources
               to be fetched, for example by activating XInclude, or by performing XSD validation using 
               <code nobreak="false">xsi:schema-location</code>.</p>
               </item>
               <item>
                  <p>Implicit access to third-party libraries supporting (for example) collations
            or localization.</p>
               </item>
            </ulist>
            <p>External resources are always referenced by means of a URI. The way in which a URI
         is dereferenced to obtain a resource is <termref def="dt-implementation-defined"/>.
         It is <rfc2119>recommended</rfc2119> that popular URI schemes such as <code nobreak="false">http</code>, <code nobreak="false">https</code>,
         and <code nobreak="false">file</code> should be supported, but this <rfc2119>may</rfc2119> be subject to user configuration and security
         constraints. Implementations are free to support indirection mechanisms such as catalogs
         and resolver callbacks, as well as supporting additional URI schemes and protocols, whether
         standardized or not.</p>
            <p>
               <termdef id="dt-trusted" term="trusted">The static context 
            includes a boolean property called <term>trusted</term> that determines whether 
            external resources are available.</termdef> This may take the following values:</p>
            <olist>
               <item>
                  <p>
                     <term>false</term>: No external resources are available other than
               resources explicitly made available by the caller through some trusted implementation-defined
               mechanism.</p>
                  <p>
                     <termdef id="dt-untrusted" term="untrusted">Code executing 
                  with <termref def="dt-trusted"/> set to <code nobreak="false">false</code> is said to be <term>untrusted</term>.</termdef>
                  </p>
               </item>
               <item>
                  <p>
                     <term>true</term>: Trusted code has access to all the resources
               available to its immediate caller.</p>
               </item>
            </olist>
            <p>The functions <function>transform</function> and <function>load-xquery-module</function>,
            and the XSLT instruction <code nobreak="false">xsl:evaluate</code>, have an option
            allowing the trust level of the executed code to be set:</p>
            <olist>
               <item>
                  <p>If <code nobreak="false">trusted</code> is set to <code nobreak="false">true</code>, the invoked code executes
               with the same trust level as its caller.</p>
               </item>
               <item>
                  <p>If <code nobreak="false">trusted</code> is set to <code nobreak="false">false</code>, the invoked code is not able
               to access any external resources other than resources explicitly made available using
               an <termref def="dt-implementation-defined"/> mechanism under the control
               of the caller.</p>
               </item>
            </olist>
            <p>Some resources, such as XML documents, may themselves contain references to 
            other resources. For example, an XML document
            may reference external entities (including an external DTD).
          External entity expansion is recognized as a known security risk.
          Functions that invoke XML parsing (such as <function>parse-xml</function>, <code nobreak="false">doc</code>,
         or <code nobreak="false">collection</code>) therefore have a <code nobreak="false">trusted</code> option indicating
            whether the document being parsed is trusted to access external entities.
         Such access is allowed only if (a) the <code nobreak="false">trusted</code> option is set to <code nobreak="false">true</code>, 
         or (b) access to the external entity in question is explicitly enabled by the caller.</p>
            <note>
               <p>The term <term>explicitly enabled</term> is not intended to mean that 
         every resource to which access is permitted must be individually listed. The mechanism
         for enabling access might provide access to a class of resources (for example, all
         resources accessible using the HTTPS protocol, or all resources within the containing
         XML database having particular access permissions). The mechanism might also take account of other
         criteria, for example it might impose limits on the size or other characteristics of the resources
         accessed.</p>
            </note>
            <p>It is <rfc2119>recommended</rfc2119> that any external API used to 
            invoke XPath, XQuery, or XSLT processing should
         similarly offer the ability to indicate whether the code
         being executed is <termref def="dt-trusted"/>.</p>
            <p>In the interests of security, the default for these options is <term>false</term>.
         However, for backwards compatibility reasons, processors <rfc2119>may</rfc2119> provide
         an option whereby a trusted user can change the default.</p>
            <p>In general, when an application requests access to an external resource which is
         not available because the application is untrusted, the processor <rfc2119>should</rfc2119> behave
         in the same way as if the resource did not exist. However, the processor <rfc2119>may</rfc2119>
         choose to disclose in its diagnostics why the request was unsuccessful.</p>
            <p>A processor <rfc2119>may</rfc2119> (but is not <rfc2119>required</rfc2119> to) 
            limit an application’s consumption of resources such as CPU cycles
         and memory when the application is untrusted.</p>
            <p>
               <termdef id="dt-available-docs" term="available documents">The term
         <term>available documents</term> refers (TODO: for the time being) to the set
         of XML documents that an application is able to access by URI.</termdef>
            </p>
         </div2>
         <div2 id="id-processing-model">
            <head>Processing Model</head>
            <changes>
               <change issue="1343" PR="1344" date="2024-09-03">
             The static typing option has been dropped.
           </change>
            </changes>
            <p>The semantics of XQuery 4.0 are defined in terms
                         of the <termref def="dt-datamodel">data
                         model</termref> and the <termref def="dt-expression-context">expression
                         context</termref>.</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink"
                     source="procmod-xquery.svg"
                     alt="Processing                          Model Overview"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="embed"
                     xlink:actuate="onLoad"/>
            <p>Figure 1:
                         Processing Model Overview</p>
            <p>Figure 1 provides a schematic overview of the processing steps that
are discussed in detail below. Some of these steps are completely
outside the domain of XQuery 4.0; in Figure 1, these are depicted
outside the line that represents the boundaries of the language, an
area labeled <term>external processing</term>. The external processing
domain includes generation of <termref def="dt-data-model-instance">XDM instances</termref> that represent the data to be queried (see <specref ref="id-data-model-generation"/>), schema import processing (see
<specref ref="id-schema-import-processing"/>), and serialization<phrase role="xquery"> (see
<specref ref="id-serialization"/>)</phrase>. The area inside the boundaries of
the language is known as the <phrase role="xquery">
                  <term>query processing domain</term>
               </phrase>, which includes the static
analysis and dynamic evaluation phases (see <specref ref="id-expression-processing"/>).  Consistency constraints on the
<phrase role="xquery">query</phrase>
             processing domain are defined in <specref ref="id-consistency-constraints"/>.</p>
            <div3 id="id-data-model-generation">
               <head>Data Model Generation</head>
               <p>The input data for <phrase role="xquery">a query</phrase>
                must be represented as one or more <termref def="dt-data-model-instance">XDM instances</termref>. This process occurs outside
the domain of XQuery 4.0, which is why Figure 1 represents it in the
external processing domain.</p>
               <p>In many cases the input data might originate as XML.
               Here are some steps by which an XML
document might be converted to an <termref def="dt-data-model-instance">XDM instance</termref>:</p>
               <olist>
                  <item>
                     <p id="DM1">A document may be parsed using an XML parser that
generates an <term>XML Information Set</term> (see <bibref ref="XINFO"/>). The parsed document may then be validated against one
or more schemas. This process, which is described in <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                             href="http://www.w3.org/TR/xmlschema-1/"
                             xlink:type="simple"
                             xlink:show="replace"
                             xlink:actuate="onRequest">[XML Schema 1.0 Part 1]</loc> or
<loc xmlns:xlink="http://www.w3.org/1999/xlink"
                             href="http://www.w3.org/TR/xmlschema11-1/"
                             xlink:type="simple"
                             xlink:show="replace"
                             xlink:actuate="onRequest">[XML Schema 1.1 Part 1]</loc>, results in an abstract information structure called
the <term>Post-Schema Validation Infoset</term> (PSVI). If a document
has no associated schema, its Information Set is preserved. (See DM1
in Figure 1)</p>
                  </item>
                  <item>
                     <p id="DM2">The Information Set or PSVI may be
transformed into an <termref def="dt-data-model-instance">XDM instance</termref>
by a process described in <bibref ref="xpath-datamodel-40"/>. (See DM2 in
Figure 1)</p>
                  </item>
               </olist>
               <p id="DM3">The above steps provide an example of how an <termref def="dt-data-model-instance">XDM instance</termref> might be constructed. An XDM instance might
also be constructed in some other way (see DM3 in Figure 1), for example it might be 
synthesized directly from a relational database, or
derived by parsing a JSON text or a CSV file. Whatever the origin, XQuery 4.0 is defined in terms
of the <termref def="dt-datamodel">data model</termref>,
but it does not place any constraints on how XDM instances are constructed.</p>
               <p>The remainder of this section is concerned with the common case where XML data is being processed.</p>
               <p>
                  <termdef term="type annotation" id="dt-type-annotation">Each element node and attribute node in an <termref def="dt-data-model-instance">XDM instance</termref> has a <term>type annotation</term> (described in <xspecref spec="DM40" ref="types"/>). 
The type annotation of a node is a reference to a <termref def="dt-schema-type"/>. 
</termdef>  The <code nobreak="false">type-name</code> of a node is the name of the type referenced by its <termref def="dt-type-annotation">type annotation</termref> (but note that the
               type annotation can be a reference to an anonymous type). 
If the <termref def="dt-data-model-instance">XDM instance</termref> was derived from a validated XML document as described in <xspecref spec="DM40" ref="const-psvi"/>, the type annotations of the element and attribute nodes are derived from schema
validation. XQuery 4.0 does
not provide a way to directly access the type annotation of an element
or attribute node.</p>
               <p>The value of an attribute is represented directly within the
attribute node. An attribute node whose type is unknown (such as might
occur in a schemaless document) is given the <termref def="dt-type-annotation">type annotation</termref>
                  <code nobreak="false">xs:untypedAtomic</code>.</p>
               <p>The value of an element is represented by the children of the
element node, which may include text nodes and other element
nodes. The <termref def="dt-type-annotation">type annotation</termref> of an element node indicates how the values in
its child text nodes are to be interpreted. An element that has not been validated (such as might occur in a schemaless document) is annotated
with the <termref def="dt-schema-type"/>
                  <code nobreak="false">xs:untyped</code>. An element that has been validated and found to be partially valid is annotated with the schema type <code nobreak="false">xs:anyType</code>. If an element node is annotated as <code nobreak="false">xs:untyped</code>, all its descendant element nodes are also annotated as <code nobreak="false">xs:untyped</code>. However, if an element node is annotated as <code nobreak="false">xs:anyType</code>, some of its descendant element nodes may have a more specific <termref def="dt-type-annotation">type annotation</termref>.</p>
            </div3>
            <div3 id="id-schema-import-processing">
               <head>Schema Import Processing</head>
               <p role="xquery">The <termref def="dt-issd">in-scope
schema definitions</termref> in the <termref def="dt-static-context">static context</termref> may be extracted from
actual XML schemas (see step SI1 in Figure 1) or may be
generated by some other mechanism (see step SI2 in Figure 1). In
either case, the result must satisfy the consistency constraints
defined in <specref ref="id-consistency-constraints"/>.</p>
            </div3>
            <div3 id="id-expression-processing">
               <head>Expression
Processing</head>
               <p>XQuery 4.0 defines two phases of processing called
the <termref def="dt-static-analysis">static analysis phase</termref>
and the <termref def="dt-dynamic-evaluation">dynamic evaluation
phase</termref> (see Figure 1).  During the static analysis phase, <termref def="dt-static-error">static errors</termref>,  <termref def="dt-dynamic-error">dynamic errors</termref>, or <termref def="dt-type-error">type errors</termref> may be raised. During the dynamic evaluation phase, only <termref def="dt-dynamic-error">dynamic errors</termref> or <termref def="dt-type-error">type errors</termref> may be raised. These kinds of errors are defined in <specref ref="id-kinds-of-errors"/>.  </p>
               <p>Within each phase, an implementation is free to use any
strategy or algorithm whose result conforms to the
specifications in this document.</p>
               <div4 id="id-static-analysis">
                  <head>Static Analysis Phase</head>
                  <p>
                     <termdef id="dt-static-analysis" term="static analysis phase">The
<term>static analysis phase</term> depends on the expression itself
and on the <termref def="dt-static-context">static context</termref>. The <term>static analysis phase</term> does
not depend on input data (other than schemas).</termdef>
                  </p>
                  <p id="SQ1234">During the static analysis phase, the <phrase role="xquery">query</phrase>
                   is typically parsed into an
internal representation called the <term>operation tree</term> (step
SQ1 in Figure 1).  A parse error is raised as a <termref def="dt-static-error">static error</termref>
                     <errorref class="ST" code="0003"/>. The <termref def="dt-static-context">static context</termref> is initialized by the implementation (step SQ2). <phrase role="xquery">The <termref def="dt-static-context">static context</termref> is then changed and augmented based on information in the
                        <term>prolog</term> (step SQ3). 
                        The static context is extended with function
                        declarations and variable declarations from imported modules.
                        If the <termref def="dt-schema-aware-feature">Schema Aware Feature</termref>
                        is supported, the <termref def="dt-issd">in-scope schema definitions</termref> are populated with information from imported schemas. 
                        </phrase> The <termref def="dt-static-context">static context</termref> is used to resolve schema type names, function names, namespace prefixes, and variable names (step
SQ4).
If a name of one of these kinds in the <term>operation tree</term> is
not found in the <termref def="dt-static-context">static context</termref>, a <termref def="dt-static-error">static error</termref> (<errorref class="ST" code="0008"/> or <errorref class="ST" code="0017"/>) is raised (however, see exceptions to this rule in <specref ref="id-element-test"/> and <specref ref="id-attribute-test"/>.)</p>
                  <p id="SQ5">The <term>operation tree</term> is then typically
normalized by making explicit the implicit operations
such as <termref def="dt-atomization">atomization</termref> and extraction of <termref def="dt-ebv">effective boolean values</termref> (step SQ5).</p>
                  <p>During the <termref def="dt-static-analysis">static analysis
phase</termref>, a processor may perform type analysis. The
effect of type analysis is to assign a <termref def="dt-static-type">static type</termref> to each expression in the
operation tree. <termdef id="dt-static-type" term="static type">The
<term>static type</term> of an expression is the best inference that
the processor is able to make statically about the type of the result
of the expression.</termdef> This specification does not define the
rules for type analysis nor the static types that are assigned to
particular expressions: the only constraint is that the inferred type
must match all possible values that the expression is capable of
returning.</p>
                  <p>Examples of inferred static types might be:</p>
                  <ulist>
                     <item>
                        <p>For the expression <code nobreak="false">concat(a,b)</code> the inferred static type is <code nobreak="false">xs:string</code>
                        </p>
                     </item>
                     <item>
                        <p>For the expression <code nobreak="false">$a = $v</code> the inferred static type is <code nobreak="false">xs:boolean</code>
                        </p>
                     </item>
                     <item>
                        <p>For the expression <code nobreak="false">$s[exp]</code> the inferred static
    type has the same item type as the static type of <code nobreak="false">$s</code>,
    but a cardinality that allows the empty sequence even if the
    static type of <code nobreak="false">$s</code> does not allow the empty
    sequence.</p>
                     </item>
                     <item>
                        <p>The inferred static type of the expression <code nobreak="false">data($x)</code> (whether written
    explicitly or inserted into the operation tree in places where atomization
    is implicit) depends on the inferred static type of <code nobreak="false">$x</code>: for example, if <code nobreak="false">$x</code>
    has type <code nobreak="false">element(*, xs:integer)</code> then <code nobreak="false">data($x)</code> has static type <code nobreak="false">xs:integer</code>.</p>
                     </item>
                  </ulist>
                  <p>In XQuery 1.0 and XPath 2.0, rules for static type inferencing were published
normatively in <bibref ref="xquery-semantics"/>, but implementations were allowed to
refine these rules to infer a more precise type where possible. In
subsequent versions, the rules for static type inferencing are entirely implementation-dependent.</p>
                  <p>Every kind of expression also imposes requirements on the type of its
operands. For example, with the expression <code nobreak="false">substring($a, $b, $c)</code>, <code nobreak="false">$a</code> must be
of type <code nobreak="false">xs:string</code> (or something that can be converted to <code nobreak="false">xs:string</code> by the
function calling rules), while <code nobreak="false">$b</code> and <code nobreak="false">$c</code> must be numeric.</p>
                  <p>A processor <rfc2119>may</rfc2119> raise a type
                  error during static analysis if the inferred static type of an
                     expression has no overlap (intersection) with the required type, and cannot be converted
                     to the required type using the <termref def="dt-coercion-rules"/>. For example,
                     given the call <code nobreak="false">fn:upper-case($s)</code>, the processor <rfc2119>may</rfc2119> raise an error if the
                     declared or inferred type of <code nobreak="false">$s</code> is <code nobreak="false">xs:integer</code>, 
                     but not if it is <code nobreak="false">xs:anyAtomicType</code>.
                  </p>
                  <p>In addition, type analysis <rfc2119>may</rfc2119> conclude that an expression is <termref def="dt-implausible"/>.
               Implausible expressions may be considered erroneous unless such checks have been disabled.
               For example, the expression <code nobreak="false">round(tokenize($input))</code> is implausible because 
                  the required type for <function>fn:round</function> is <code nobreak="false">xs:numeric?</code>,
                  while the static type of <code nobreak="false">tokenize($input)</code> is <code nobreak="false">xs:string*</code>,
                  and these two sequence types are <termref def="dt-substantively-disjoint"/>.
               This topic is described further in <specref ref="id-implausible-expressions"/>.</p>
                  <p>Alternatively, the processor
                  <rfc2119>may</rfc2119> defer all type checking until the dynamic evaluation phase.</p>
               </div4>
               <div4 id="id-dynamic-evaluation">
                  <head>Dynamic Evaluation Phase</head>
                  <p id="DQ12345">
                     <termdef id="dt-dynamic-evaluation" term="dynamic evaluation phase">The <term>dynamic evaluation phase</term> is the phase during which the value of an expression is computed.</termdef> It is dependent on successful completion of the <termref def="dt-static-analysis">static analysis phase</termref>.</p>
                  <p>The dynamic evaluation phase can occur only if no errors were detected during the <termref def="dt-static-analysis">static analysis phase</termref>.</p>
                  <p>The dynamic evaluation phase depends on the <term>operation
tree</term> of the expression being evaluated (step DQ1), on the input
data (step DQ4), and on the <termref def="dt-dynamic-context">dynamic context</termref> (step DQ5), which in turn draws information from  the external environment (step DQ3) and the <termref def="dt-static-context">static context</termref> (step DQ2). The dynamic evaluation phase may create new data-model values (step DQ4) and it may extend the <termref def="dt-dynamic-context">dynamic context</termref> (step DQ5)—for example, by binding values to variables.</p>
                  <p diff="chg" at="B">
                     <termdef term="dynamic type" id="dt-dynamic-type">
                  Every value matches one or more <termref def="dt-sequence-type">sequence types</termref>. 
                     A value is said to have a <term>dynamic type</term>
                        <var>T</var> if it matches (or <term>is an instance of</term>) 
                     the sequence type <var>T</var>.</termdef>
                  </p>
                  <p diff="chg" at="B">In many cases (but not all), one of the dynamic types that a value matches will 
                     be a subtype of all the others, in which case it makes sense to speak of “the dynamic type” of the value as 
                     meaning this single most specific type. In other cases (examples are 
                     <xtermref spec="DM40" ref="dt-empty-map">empty maps</xtermref> and 
                     <xtermref spec="DM40" ref="dt-empty-array">empty arrays</xtermref>) none of the 
                     dynamic types is more specific than all the others.</p>
                  <note diff="chg" at="B">
                     <p>An atomic item has a <termref def="dt-type-annotation"/> which will always be
                  a <termref def="dt-subtype"/> of all the other types that it matches; we can therefore refer to 
                  this as the <termref def="dt-dynamic-type"/> of the atomic item without ambiguity.</p>
                  </note>
                  <p diff="chg" at="B">A value may match a dynamic type that is more specific than the <termref def="dt-static-type"/> 
                  of the expression that computed it (for example, the static type of an expression might be <code nobreak="false">xs:integer*</code>, 
                  denoting a sequence of zero or more integers, but at evaluation time its value may be an instance of <code nobreak="false">xs:integer</code>, 
                  denoting exactly one integer).
               </p>
                  <p diff="chg" at="B">If an operand of an expression does not have a <termref def="dt-dynamic-type">dynamic type</termref> that is a <termref def="dt-subtype"/> of the <termref def="dt-static-type"/>
                  required for that operand, a <termref def="dt-type-error">type error</termref> is
                  raised <errorref class="TY" code="0004"/>.</p>
                  <p>Even though static typing can catch many <termref def="dt-type-error">type errors</termref> before an expression is executed, it is possible for an expression to raise an error during evaluation that was not detected by static  analysis. For example, an expression may contain a cast of a string into an integer, which is statically valid. However, if the actual value of the string at run time cannot be cast into an integer, a <termref def="dt-dynamic-error">dynamic error</termref> will result. Similarly, an expression may apply an arithmetic operator to a value whose <termref def="dt-static-type">static type</termref> is <code nobreak="false">xs:untypedAtomic</code>. This is not a <termref def="dt-static-error">static error</termref>, but at run time, if the value cannot be successfully cast to a <termref def="dt-numeric">numeric</termref> type, a <termref def="dt-dynamic-error">dynamic error</termref> will be raised.</p>
               </div4>
            </div3>
            <div3 id="id-input-sources">
               <head>Input Sources</head>
               <p>XQuery 4.0 has a set of functions that provide access to XML documents (<function>fn:doc</function>, <function>fn:doc-available</function>), collections (<function>fn:collection</function>, <function>fn:uri-collection</function>), text files (<function>fn:unparsed-text</function>, <function>fn:unparsed-text-lines</function>, <function>fn:unparsed-text-available</function>), and environment variables (<function>fn:environment-variable</function>, <function>fn:available-environment-variables</function>).  These functions are defined in <xspecref spec="FO40" ref="fns-on-docs"/>.</p>
               <p>An expression can access input data either by calling one
               of these input functions or by referencing some part of the
               <termref def="dt-dynamic-context">dynamic context</termref> that is initialized by the external
               environment, such as a <termref def="dt-variable-values">variable</termref> or
               <termref def="dt-context-value"/>.</p>
               <note>
                  <p>The <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                          href="http://expath.org"
                          xlink:type="simple"
                          xlink:show="replace"
                          xlink:actuate="onRequest">EXPath Community Group</loc> has developed a <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                          href="http://expath.org/spec/file"
                          xlink:type="simple"
                          xlink:show="replace"
                          xlink:actuate="onRequest">File Module</loc>, which some implementations use to perform file system related operations 
                  such as reading or writing files and directories. Multiple files can be read or written 
                  from a single query.</p>
               </note>
            </div3>
            <div3 id="id-serialization">
               <head>Serialization</head>
               <p>
                  <termdef id="dt-serialization" term="serialization">
                     <term>Serialization</term> is the process of
converting an <termref def="dt-data-model-instance">XDM
instance</termref> to a sequence of octets (step DM4 in Figure 1.),
as described in <bibref ref="xslt-xquery-serialization-40"/>.</termdef>
               </p>
               <p role="xquery">Although serialization of XQuery results is outside
            the scope of this specification, syntax is provided in the query
            prolog to enable default serialization options to be defined.
            See <specref ref="id-output-declarations"/>.</p>
               <p role="xquery">Serialization can also be invoked from within a query
               by calling the <function>fn:serialize</function> function.</p>
               <note>
                  <p>This definition of serialization is the definition
used in this specification. Any form of serialization that is
not based on <bibref ref="xslt-xquery-serialization-40"/> is outside
the scope of the XQuery 4.0 specification.</p>
               </note>
               <p role="xquery">An XQuery implementation is not required to provide a
serialization interface. For example, an implementation may 
provide only a DOM interface (see <bibref ref="DOM"/>) or an interface
based on an event stream. </p>
            </div3>
            <div3 id="id-consistency-constraints">
               <head>Consistency Constraints</head>
               <p>In order for XQuery 4.0 to
be well defined, the input <termref def="dt-data-model-instance">XDM instances</termref>, the <termref def="dt-static-context">static context</termref>, and the <termref def="dt-dynamic-context">dynamic context</termref> must be mutually
consistent. The consistency constraints listed below are prerequisites
for correct functioning of an XQuery 4.0 implementation. Enforcement
of these consistency constraints is beyond the scope of this
specification. This specification does not
define the result of  <phrase role="xquery">a query</phrase>
                under any condition in which one
or more of these constraints is not satisfied.</p>
               <ulist>
                  <item>
                     <p>For every  node that has a type annotation, if that type annotation is found in the <termref def="dt-issd">in-scope schema definitions</termref> (ISSD), then its definition in the ISSD must be 
                     <phrase diff="chg" at="Issue451">
                           <xtermref ref="dt-schema-compatible" spec="DM40">compatible</xtermref>
                        </phrase> with its definition 
                     in the <xtermref ref="dt-schema" spec="DM40">schema</xtermref> that was used to validate the node. 
                  </p>
                  </item>
                  <item>
                     <p>Every element name, attribute name, or schema type name referenced in <termref def="dt-in-scope-variables"/> or <termref def="dt-statically-known-function-definitions"/>
                         must be in the <termref def="dt-issd">in-scope schema definitions</termref>, unless it is an element name referenced as part of an <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt> or an attribute name referenced as part of an <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt>.</p>
                  </item>
                  <item>
                     <p>Any reference to a global element, attribute, or type name in
the <termref def="dt-issd">in-scope schema definitions</termref> must have a corresponding element, attribute or type
definition in the <termref def="dt-issd">in-scope schema definitions</termref>.</p>
                  </item>
                  <item>
                     <p>For each (variable, type) pair in <termref def="dt-in-scope-variables">in-scope variables</termref> and the corresponding (variable, value) pair in <termref def="dt-variable-values">variable values</termref> such that the variable names are equal, the value must match the type, using the matching rules in  <specref ref="id-sequencetype-matching"/>.</p>
                  </item>
                  <item role="xquery">
                     <p>For each variable declared as external, if the variable declaration does
not include a <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$spec = xquery40--></nt>, the external environment must provide a value
for the variable.</p>
                     <p>For each variable declared as external for which the external environment
provides a value: If the variable declaration includes a declared type,
the value provided by the external environment must match the
declared type, using the matching rules in  <specref ref="id-sequencetype-matching"/>. If the variable declaration does not include a declared type, the
external environment must provide a type to accompany the value provided, using the same matching rules.</p>
                  </item>
                  <item role="xquery">
                     <p>For each function declared as external: the function’s <termref def="dt-function-item">implementation</termref> must either return a value that matches the declared result type,
using the matching rules in <specref ref="id-sequencetype-matching"/>, or raise an
<termref def="dt-implementation-defined">implementation-defined</termref> error.</p>
                  </item>
                  <item role="xquery">
                     <p>For a given query, define a <term>participating ISSD</term> as the <termref def="dt-issd">in-scope schema definitions</termref> of a module that is used in evaluating the query.
                     All participating ISSDs must be <xtermref spec="DM40" ref="dt-schema-compatible">compatible</xtermref>.</p>
                     <note diff="add" at="Issue451">
                        <p>This rule ensures that when one module <var>M</var> imports schema <var>X</var>, and another
                     module <var>N</var> imports schema <var>Y</var>, then an element node validated
                        against type <var>T</var> in <var>M</var> can be safely passed to a function
                        in <var>N</var> that expects an argument of type <code nobreak="false">element(*, T)</code>.
                     The requirement for compatibility does not guarantee that in all cases, validation
                     of an element against the two different schemas will produce exactly the same outcome
                     (there may be differences, for example, in the definition of substitution groups
                     or wildcards), and the processor must allow for such differences.</p>
                     </note>
                  </item>
                  <item>
                     <p>In the <termref def="dt-static-namespaces">statically known namespaces</termref>, the prefix <code nobreak="false">xml</code> must not be bound to any namespace URI other than <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>, and no prefix other than <code nobreak="false">xml</code> may be bound to this namespace URI.
The prefix <code nobreak="false">xmlns</code> must not be bound to any namespace URI, and no prefix may be bound to the namespace URI <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.</p>
                  </item>
               </ulist>
            </div3>
         </div2>
         <div2 id="errors">
            <head>Error Handling</head>
            <div3 id="id-kinds-of-errors">
               <head>Kinds of Errors</head>
               <p>
As described in <specref ref="id-expression-processing"/>, XQuery 4.0
defines a <termref def="dt-static-analysis">static analysis phase</termref>, which does not depend on input
data, and a <termref def="dt-dynamic-evaluation">dynamic evaluation
phase</termref>, which does depend on input
data.  Errors may be raised during each phase.</p>
               <p>
                  <termdef id="dt-static-error" term="static error">
An error that can be detected during the static analysis phase, and is not a type error, is a <term>static error</term>.</termdef> A syntax error is an example of a <termref def="dt-static-error">static error</termref>.</p>
               <p>
                  <termdef id="dt-dynamic-error" term="dynamic error">A <term>dynamic
error</term> is an error that
must be detected during the dynamic evaluation phase and may be detected
during the static analysis phase.</termdef>
Numeric overflow is an example of a <termref def="dt-dynamic-error">dynamic error</termref>.
            </p>
               <p>
                  <termdef id="dt-type-error" term="type error">A <term>type
error</term> may be raised during the static analysis phase or the dynamic evaluation phase.
During the static analysis phase, a <termref def="dt-type-error">type error</termref> occurs
when the <termref def="dt-static-type">static type</termref> of an expression does not match the expected type
of the context in which the expression occurs.
During the dynamic evaluation phase, a <termref def="dt-type-error">type error</termref> occurs
when the <termref def="dt-dynamic-type">dynamic type</termref> of a value does not match the expected type of
the context in which the value occurs.</termdef>
               </p>
               <p>The outcome of the <termref def="dt-static-analysis">static analysis
phase</termref> is either success or one or more <termref def="dt-type-error">type errors</termref>, <termref def="dt-static-error">static errors</termref>, or statically detected <termref def="dt-dynamic-error">dynamic errors</termref>. The result of the <termref def="dt-dynamic-evaluation">dynamic evaluation
phase</termref> is either a result value, a <termref def="dt-type-error">type
error</termref>, or a <termref def="dt-dynamic-error">dynamic error</termref>.</p>
               <p>If more than one error is present, or if an error condition comes within the
scope of more than one error defined in this specification, then any non-empty
subset of these errors may be reported.</p>
               <p>If an implementation can determine during the
<termref def="dt-static-analysis">static
analysis phase</termref> that <phrase role="xquery">a <nt def="prod-xquery40-QueryBody">QueryBody<!--$spec = xquery40--></nt>
                  </phrase>
               , if evaluated, would necessarily
raise a <termref def="dt-dynamic-error">dynamic error</termref> or that an expression, if evaluated, would necessarily raise a <termref def="dt-type-error">type error</termref>, the implementation may (but is not required to) report that
error during the <termref def="dt-static-analysis">static
analysis phase</termref>.</p>
               <p>An implementation can raise a <termref def="dt-dynamic-error">dynamic error</termref> for <phrase role="xquery">a <nt def="prod-xquery40-QueryBody">QueryBody<!--$spec = xquery40--></nt>
                  </phrase>
                statically only if the <phrase role="xquery">query</phrase>
                can never execute without raising that error, as in the following example:</p>
               <eg role="parse-test" xml:space="preserve">
error()
</eg>
               <p>The following example contains a type error, which can be reported statically even if the implementation can not prove that the expression will actually be evaluated.</p>
               <eg role="parse-test" xml:space="preserve">
if (empty($arg))
then "cat" * 2
else 0
</eg>
               <p>
                  <termdef id="dt-warning" term="warning">In addition to <termref def="dt-static-error">static errors</termref>, <termref def="dt-dynamic-error">dynamic errors</termref>, and <termref def="dt-type-error">type
errors</termref>, an XQuery 4.0
implementation may raise <term>warnings</term>, either during the <termref def="dt-static-analysis">static analysis
phase</termref> or the
<termref def="dt-dynamic-evaluation">dynamic evaluation
phase</termref>. The circumstances in which warnings are raised, and
the ways in which warnings are handled, are <termref def="dt-implementation-defined">implementation-defined</termref>.</termdef>
               </p>
               <p>In addition to the errors defined in this
specification, an implementation may raise a <termref def="dt-dynamic-error">dynamic error</termref> for a reason beyond the scope of this specification. For
example, limitations may exist on the maximum
numbers or sizes of various objects. 
<phrase id="id-error-limit-exceeded">An error must be raised if such a limitation is exceeded  <errorref class="DY" code="0130"/>.</phrase>
               </p>
            </div3>
            <div3 id="id-identifying-errors">
               <head>Identifying and Reporting Errors</head>
               <p>The errors defined in this specification are identified by QNames that have the form 
               <code role="xquery" nobreak="false">err:XXYYnnnn</code>, where:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">err</code> denotes the namespace for XPath and XQuery errors, <code nobreak="false">http://www.w3.org/2005/xqt-errors</code>. This binding of the namespace prefix <code nobreak="false">err</code> is used for convenience in this document, and is not normative.</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <code nobreak="false">XX</code> denotes the language in which the error is defined, using the following encoding:</p>
                     <ulist role="xquery">
                        <item>
                           <p>
                              <code nobreak="false">XP</code> denotes an error defined by XPath. Such an error may also occur XQuery since XQuery  includes XPath as a subset.</p>
                        </item>
                        <item>
                           <p>
                              <code nobreak="false">XQ</code> denotes an error defined by XQuery (or an error originally defined by XQuery and later added to XPath).</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">YY</code> denotes the error category, using the following encoding:</p>
                     <ulist>
                        <item>
                           <p>
                              <code nobreak="false">ST</code> denotes a static error.</p>
                        </item>
                        <item>
                           <p>
                              <code nobreak="false">DY</code> denotes a dynamic error.</p>
                        </item>
                        <item>
                           <p>
                              <code nobreak="false">TY</code> denotes a type error.</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">nnnn</code> is a unique numeric code.</p>
                  </item>
               </ulist>
               <note>
                  <p>The namespace URI for  XPath and XQuery errors is not expected to
change from one version of <phrase role="xquery">XQuery</phrase>
                   to another. However, the contents of this
namespace may be extended to include additional error definitions.</p>
               </note>
            </div3>
            <div3 id="id-handling-dynamic">
               <head>Handling Dynamic Errors</head>
               <p>Except as noted in this document, if any operand of an expression
raises a <termref def="dt-dynamic-error">dynamic error</termref>, the expression also raises a <termref def="dt-dynamic-error">dynamic error</termref>.
If an expression can validly return a value or raise a dynamic
error, the implementation may choose to return the value or raise
the dynamic error (see <specref ref="id-errors-and-opt"/>).  For example, the logical expression
<code nobreak="false">expr1 and expr2</code> may return the value <code nobreak="false">false</code>
if either operand returns <code nobreak="false">false</code>,
or may raise a dynamic error if either operand raises a dynamic
error.</p>
               <p> If more than one operand of an expression raises
an error, the
implementation may choose which error is raised by the expression.
For example, in this expression:

</p>
               <eg role="parse-test" xml:space="preserve">($x div $y) + xs:decimal($z)</eg>
               <p>

both the sub-expressions <code role="parse-test" nobreak="false">($x div $y)</code> and <code role="parse-test" nobreak="false">xs:decimal($z)</code> may
raise an error.  The
implementation may choose which error is raised by the <code nobreak="false">+</code>
expression.  Once one operand raises an error, the implementation is
not required, but is permitted, to evaluate any other operands.</p>
               <p>
                  <termdef id="dt-error-value" term="error value">In addition to its identifying QName, a dynamic error may also carry a descriptive string and one or more additional values called <term>error values</term>.</termdef> An implementation may provide a mechanism whereby an application-defined error handler can process error values and produce diagnostic messages. 
  <phrase role="xquery">XQuery 3.1 provides standard error handling via <xspecref spec="XQ40" ref="id-try-catch"/>.</phrase>
               </p>
               <p>A dynamic error may be raised by a <termref def="dt-system-function">system
function</termref> or operator.  For example,
the <code nobreak="false">div</code> operator raises an error if its operands are <code nobreak="false">xs:decimal</code> values and its second operand
is equal to zero. Errors raised by system functions and operators are defined in <bibref ref="xpath-functions-40"/> or the host language.</p>
               <p>A dynamic error can also be raised explicitly by calling the
<function>fn:error</function> function, which always raises a dynamic error and never
returns a value.  This function is defined in <xspecref spec="FO40" ref="func-error"/>. For example, the following
function call raises a dynamic
error, providing a QName that identifies the error, a descriptive string, and a diagnostic value (assuming that the prefix <code nobreak="false">app</code> is bound to a namespace containing application-defined error codes):</p>
               <eg role="parse-test" xml:space="preserve">error( #app:err057, "Unexpected value", string($v) )</eg>
            </div3>
            <div3 id="id-errors-and-opt">
               <head>Errors and
      Optimization</head>
               <p>Because different implementations may
      choose to evaluate or optimize an expression in different ways,
      certain aspects of raising <termref def="dt-dynamic-error">dynamic errors</termref> are <termref def="dt-implementation-dependent">implementation-dependent</termref>, as described in this section.</p>
               <p>An implementation is always free to evaluate the operands of an operator in any order.</p>
               <p>In some cases,  a processor can determine the result of an expression without accessing all the data that would be implied by the formal expression semantics. For example, the formal description of <termref def="dt-filter-expression">filter expressions</termref> suggests that <code role="parse-test" nobreak="false">$s[1]</code> should be evaluated by examining all the items in sequence <code nobreak="false">$s</code>, and selecting all those that satisfy the predicate <code role="parse-test" nobreak="false">position()=1</code>. In practice, many implementations will recognize that they can evaluate this expression by taking the first item in the sequence and then exiting. If <code nobreak="false">$s</code> is defined by an expression such as <code role="parse-test" nobreak="false">//book[author eq 'Berners-Lee']</code>, then this strategy may avoid a complete scan of a large document and may therefore greatly improve performance. However, a consequence of this strategy is that a dynamic error or type error that would be detected if the expression semantics were followed literally might not be detected at all if the evaluation exits early. In this example, such an error might occur if there is a <code nobreak="false">book</code> element in the input data with more than one <code nobreak="false">author</code> subelement.</p>
               <p>The extent to which a processor may optimize its access to data, at the cost of not raising errors, is defined by the following rules.</p>
               <p>Consider an expression <emph>Q</emph> that has an operand (sub-expression) <emph>E</emph>. In general the value of <emph>E</emph> is a sequence. At an intermediate stage during evaluation of the sequence, some of its items will be known and others will be unknown. If, at such an intermediate stage of evaluation, a processor is able to establish that there are only two possible outcomes of evaluating <emph>Q</emph>, namely the value <emph>V</emph> or an error, then the processor may deliver the result <emph>V</emph> without evaluating further items in the operand <emph>E</emph>. For this purpose, two values are considered to represent the same outcome if their items are pairwise the same, where nodes are the same if they have the same identity, and values are the same if they are equal and have exactly the same type.</p>
               <p>There is an exception to this rule: If a processor evaluates an operand <emph>E</emph> (wholly or in part), then it  is required to establish that the actual value of the operand <emph>E</emph> does not violate any constraints on its cardinality. For example, the expression <code role="parse-test" nobreak="false">$e eq 0</code> results in a type error if the value of <code nobreak="false">$e</code> contains two or more items. A processor is not allowed to decide, after evaluating the first item in the value of <code nobreak="false">$e</code> and finding it equal to zero, that the only possible outcomes are the value <code nobreak="false">true</code> or a type error caused by the cardinality violation. It must establish that the value of <code nobreak="false">$e</code> contains no more than one item.</p>
               <p>These rules apply to all the operands of an expression considered in combination: thus if an expression has two operands <emph>E1</emph> and <emph>E2</emph>, it may be evaluated using any samples of the respective sequences that satisfy the above rules.</p>
               <p>The rules cascade: if <emph>A</emph> is an operand of <emph>B</emph> and <emph>B</emph> is an operand of <emph>C</emph>, then the processor needs to evaluate only a sufficient sample of <emph>B</emph> to determine the value of <emph>C</emph>, and needs to evaluate only a sufficient sample of <emph>A</emph> to determine this sample of <emph>B</emph>.</p>
               <p>The effect of these rules is that the processor is free to stop examining further items in a sequence as soon as it can establish that further items would not affect the result except possibly by causing an error. For example, the processor may return <code nobreak="false">true</code> as the result of the expression <code role="parse-test" nobreak="false">S1 = S2</code> as soon as it finds a pair of equal values from the two sequences.</p>
               <p>Another consequence of these rules is that where none of the items in a sequence contributes to the result of an expression, the processor is not obliged to evaluate any part of the sequence. Again, however, the processor cannot dispense with a required cardinality check: if the empty sequence is not permitted in the relevant context, then the processor must ensure that the operand is not the empty sequence.</p>
               <p>Examples:</p>
               <ulist>
                  <item>
                     <p>If an implementation can find (for example, by using an index) that at
least one item returned by <code nobreak="false">$expr1</code> in the following example has the value <code nobreak="false">47</code>, it is allowed to
return <code nobreak="false">true</code> as the result of the <code nobreak="false">some</code> expression, without searching for
another item returned by <code nobreak="false">$expr1</code> that would raise an error if it were evaluated.
</p>
                     <eg role="parse-test" xml:space="preserve">some $x in $expr1 satisfies $x = 47</eg>
                  </item>
                  <item>
                     <p>In the following example, if an implementation can find (for example, by using an index) the
<code nobreak="false">product</code> element-nodes that have an <code nobreak="false">id</code> child with the value <code nobreak="false">47</code>, it is allowed to return these nodes as the
result of the <termref def="dt-path-expression">path expression</termref>, without searching for another <code nobreak="false">product</code> node that
would raise an error because it has an <code nobreak="false">id</code> child whose value is not an integer.</p>
                     <eg role="parse-test" xml:space="preserve">//product[id = 47]</eg>
                  </item>
               </ulist>
               <!-- <change diff="chg" at="XQ.E4 and XP.E4"> -->
               <p>For a variety of reasons, including optimization, implementations
          may rewrite expressions into a different
          form. There are a number of rules that limit the extent of this freedom:
          </p>
               <ulist>
                  <item>
                     <p>
                Other than the raising or not raising of errors, the result
                of evaluating a rewritten expression must
                conform to the semantics
                defined in this specification for the original expression.
             </p>
                     <note>
                        <p>
                This allows an implementation to return a result in cases where the
                original expression would have raised an error, or to raise an error in cases
                where the original expression would have returned a result. The main cases
                where this is likely to arise in practice are (a) where a rewrite changes the
                order of evaluation, such that a subexpression causing an error is evaluated
                when the expression is written one way and is not evaluated when the expression
                is written a different way, and (b) where intermediate results of the
                evaluation cause overflow or other out-of-range conditions.
             </p>
                     </note>
                     <note>
                        <p>
                This rule does not mean that the result of the expression will always
                be the same in non-error cases as if it had not been rewritten, because there
                are many cases where the result of an expression is to some degree
                <termref def="dt-implementation-dependent">implementation-dependent</termref>
                or <termref def="dt-implementation-defined">implementation-defined</termref>.
             </p>
                     </note>
                  </item>
                  <item>
                     <p diff="add" at="B">
                     The rules described in <specref ref="id-guarded-expressions"/> ensure that for
                     certain kinds of expression (for example conditional expressions), changing the
                     order of evaluation of subexpressions does not result in dynamic errors that
                     would not otherwise occur.</p>
                  </item>
                  <item>
                     <p>
                Expressions must not be rewritten in such a way
                as to create or remove static errors.

                The static errors in this specification are defined
                for the original expression, and must be preserved if
                the expression is rewritten.</p>
                  </item>
                  <item>
                     <p>
                     As stated earlier, an expression
                     must not be rewritten to dispense with a
                     required cardinality check: for example, <code role="parse-test" nobreak="false">string-length(//title)</code>
                     must raise an
                     error if the document contains more than one title element.
                  </p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-guarded-expressions" diff="add" at="B">
               <head>Guarded Expressions</head>
               <changes>
                  <change issue="71" PR="230" date="2022-11-15">
                  The rules for “errors and optimization” have been tightened up to disallow
                  many cases of optimizations that alter error behavior. In particular
                  there are restrictions on reordering the operands of <code nobreak="false">and</code> and <code nobreak="false">or</code>,
                  and of predicates in filter expressions, in a way that might allow the processor to raise dynamic
                  errors that the author intended to prevent.
               </change>
               </changes>
               <p>
                  <termdef id="dt-guarded" term="guarded">An expression <var>E</var> is said to be <term>guarded</term>
               by some governing condition <var>C</var> if evaluation of <var>E</var> is not allowed to fail
               with a <termref def="dt-dynamic-error"/> except when <var>C</var> applies.</termdef>
               </p>
               <p>For example, in a conditional expression <code nobreak="false">if (P) then T else F</code>, the subexpression
               <var>T</var> is guarded by <var>P</var>, and the subexpression <var>F</var> is guarded by
               <code nobreak="false">not(P)</code>. One way an implementation can satisfy this rule is by not evaluating <var>T</var> unless <var>P</var>
               is true, and likewise not evaluating <var>F</var> unless <var>P</var> is false. Another
               way of satisfying the rule is for the implementation to evaluate all the subexpressions, but to catch any errors that occur 
               in a guarded subexpression so they are not propagated.
            </p>
               <p>The existence of this rule enables errors to be prevented by writing expressions such as
            <code nobreak="false">if ($y eq 0) then "N/A" else ($x div $y)</code>. This example will never fail with a divide-by-zero
            error because the <code nobreak="false">else</code> branch of the conditional is <termref def="dt-guarded"/>.</p>
               <p>Similarly, in the mapping expression <code nobreak="false">
                     <var>E1</var>!<var>E2</var>
                  </code>, the subexpression <var>E2</var> is guarded
            by the existence of an item from <var>E1</var>. This means, for example, that the expression <code nobreak="false">(1 to $n)!doc('bad.xml')</code>
            must not raise a dynamic error if <code nobreak="false">$n</code> is zero. The rule governing evaluation of guarded expressions
               is phrased so as not to disallow “loop-lifting” or “constant-folding” optimizations 
               whose aim is to avoid repeated evaluation of a common subexpression;
            but such optimizations must not result in errors that would not otherwise occur.</p>
               <p>The complete list of expressions that have guarded subexpressions is as follows:</p>
               <ulist>
                  <item>
                     <p>In a conditional expression (<nt def="doc-xquery40-IfExpr">IfExpr<!--$spec = xquery40--></nt>) the <code nobreak="false">then</code> branch
                  is guarded by the condition being true, and the <code nobreak="false">else</code> branch
                  is guarded by the condition being false.</p>
                  </item>
                  <item role="xquery">
                     <p>In a <code nobreak="false">switch</code> expression (<nt def="doc-xquery40-SwitchExpr">SwitchExpr<!--$spec = xquery40--></nt>), 
               the <code nobreak="false">return</code> expression of a particular <code nobreak="false">case</code> is guarded by the condition for that case
               matching, and no earlier case matching.</p>
                  </item>
                  <item role="xquery">
                     <p>In a <code nobreak="false">typeswitch</code> expression (<nt def="doc-xquery40-TypeswitchExpr">TypeswitchExpr<!--$spec = xquery40--></nt>), 
                  the <code nobreak="false">return</code> expression of a particular <code nobreak="false">case</code> is guarded by the condition for that case
                  matching, and no earlier case matching.</p>
                  </item>
                  <item>
                     <p>In an <termref def="dt-and-expression"/>, the second operand
               is guarded by the value of the first operand being true.</p>
                  </item>
                  <item>
                     <p>In an <termref def="dt-or-expression"/>, the second operand
                  is guarded by the value of the first operand being false.</p>
                  </item>
                  <item>
                     <p>In an <code nobreak="false">otherwise</code> expression (<nt def="doc-xquery40-OtherwiseExpr">OtherwiseExpr<!--$spec = xquery40--></nt>), the second operand
                  is guarded by the value of the first operand being the empty sequence.</p>
                  </item>
                  <item>
                     <p>In a path expression of the form <code nobreak="false">
                           <var>E1</var>/<var>E2</var>
                        </code> 
                  or <code nobreak="false">
                           <var>E1</var>//<var>E2</var>
                        </code>, and in a mapping
               expression of the form <code nobreak="false">
                           <var>E1</var>!<var>E2</var>
                        </code>, the right-hand operand <var>E2</var> is guarded by
               the existence of at least one item in the result of evaluating <var>E1</var>.</p>
                     <p>This rule applies even if <var>E2</var> does not reference the context value.
                     For example, no dynamic error can be thrown by the expression 
               <code nobreak="false">(1 to $n)!doc('bad.xml')</code> in the case where <code nobreak="false">$n</code> is zero.</p>
                  </item>
                  <item>
                     <p>In a filter expression of the form <code nobreak="false">
                           <var>E</var>[<var>P</var>]</code>, 
                  the predicate <var>P</var> is guarded by
                  the existence of at least one item in the result of evaluating <var>E</var>.</p>
                     <p>This rule has the consequence that in a filter expression with multiple predicates, 
                  such as <code nobreak="false">
                           <var>E</var>[<var>P1</var>][<var>P2</var>]</code>,
               evaluation of <var>P2</var> must not raise a dynamic error unless <var>P1</var> returns <code nobreak="false">true</code>. This rule does
               not prevent reordering of predicates (for example, to take advantage of indexes), but it does require that any
               such reordering must not result in errors that would not otherwise occur.</p>
                  </item>
                  <item>
                     <p role="xquery">In a <code nobreak="false">FLWOR</code> expression (<nt def="doc-xquery40-FLWORExpr">FLWORExpr<!--$spec = xquery40--></nt>), an expression
                     that is logically dependent on the tuples in the tuple stream is guarded by the existence
                     of a relevant tuple. This applies even where the expression does not actually reference
                     any of the variable bindings in the tuple stream. For example, in the expression
                     <code nobreak="false">for $x in <var>S</var> return <var>E</var>
                        </code>, the expression 
                     <var>E</var> is guarded by the existence of
                        an item bound to <code nobreak="false">$x</code>.</p>
                     <p>This means that the expression <code nobreak="false">for $x in 1 to $n return doc('bad.xml')</code>
               must not raise a dynamic error in the case where <code nobreak="false">$n</code> is zero.</p>
                  </item>
                  <item>
                     <p>In a <code nobreak="false">quantified</code> expression (<nt def="doc-xquery40-QuantifiedExpr">QuantifiedExpr<!--$spec = xquery40--></nt>) such
                  as <code nobreak="false">some $x in <var>S</var> satisfies <var>P</var>
                        </code>, the expression 
                  <var>P</var> is guarded by the existence of
                     an item bound to <code nobreak="false">$x</code>.</p>
                  </item>
               </ulist>
               <p>The fact that an expression is <termref def="dt-guarded"/> does not remove the obligation to report
            <termref def="dt-static-error">static errors</termref> in the expression; nor does it remove the option
            to report statically detectable <termref def="dt-type-error">type errors</termref>.</p>
               <note>
                  <p>These rules do not constrain the order of evaluation of subexpressions. For example, given an expression
                  such as <code nobreak="false">//person[@first = "Winston"][@last = "Churchill"]</code>, or equivalently
                  <code nobreak="false">//person[@first = "Winston" and @last = "Churchill"]</code>, an implementation might use an index on the value of
                  <code nobreak="false">@last</code> to select items that satisfy the second condition, and then filter these
                  items on the value of the first condition. Alternatively, it might evaluate both predicates in parallel.
                  Or it might interpose an additional redundant condition: 
                  <code nobreak="false">//person[string-length(@first) + string-length(@last) = 16][@first = "Winston"][@last = "Churchill"]</code>.
                  But implementations must ensure that
                  such rewrites do not result in dynamic errors being reported that would not occur if the predicates
                  were evaluated in order as written.</p>
               </note>
               <note>
                  <p>Although the rules for guarded expressions prevent optimizations resulting in spurious errors, 
                  they do not prevent optimizations whose effect is to mask errors. For example, the rules guarantee that
                  <code nobreak="false">("A", 3)[. instance of xs:integer][. eq 3]</code> will not raise an error caused by the comparison
                  <code nobreak="false">("A" eq 3)</code>, but they
                  do not guarantee the converse: the expression <code nobreak="false">("A", 3)[. eq 3][. instance of xs:integer]</code>
                  may or may not raise a dynamic error.</p>
               </note>
               <note>
                  <p>The rules in this section do not disallow all expression rewrites that might result in dynamic
                  errors. For example, rewriting <code nobreak="false">($x - $y + $z)</code> as <code nobreak="false">($x + $z - $y)</code> is permitted
               even though it might result in an arithmetic overflow.</p>
               </note>
               <note>
                  <p>Some implementations allow calls on external functions that have side-effects. The semantics of
               such function calls are entirely <termref def="dt-implementation-defined"/>. Processors <rfc2119>may</rfc2119>
               choose to reference the rules for <termref def="dt-guarded"/> expressions when defining the behavior
               of such function calls, but this is outside the scope of the language specification.</p>
               </note>
            </div3>
            <div3 id="id-implausible-expressions" diff="add" at="Issue602">
               <head>Implausible Expressions</head>
               <changes>
                  <change issue="602" PR="603" date="2023-07-25">
                  The rules for reporting type errors during static analysis have been changed
                  so that a processor has more freedom to report errors in respect of constructs that
                  are evidently wrong, such as <code nobreak="false">@price/@value</code>, even though dynamic evaluation
                  is defined to return the empty sequence rather than an error.
               </change>
               </changes>
               <p>
                  <termdef id="dt-implausible" term="implausible">Certain expressions, while not
            erroneous, are classified as being <term>implausible</term>,
            because they achieve no useful effect.</termdef>
               </p>
               <p>An example of an implausible expression is <code nobreak="false">@code/text()</code>. This expression
            will always evaluate to the empty sequence, because attribute nodes cannot have text
            node children. The semantics of the expression are well defined, but it is likely
            that the user writing this expression intended something different: if they wanted to write an 
            expression that evaluated to the empty sequence, there would be easier ways to write it.</p>
               <p>Where an expression is classified (by rules in this specification) as being
            <termref def="dt-implausible"/>, a processor <rfc2119>may</rfc2119> (but is
            not <rfc2119>required</rfc2119> to) raise a static error.</p>
               <p>For reasons of backwards compatibility and interoperability, and to facilitate
            automatic generation of XQuery 4.0 code, a processor <rfc2119>must</rfc2119> 
            provide a mode of operation in which <termref def="dt-implausible"/>
            expressions are not treated as static errors, but are evaluated
            with the defined semantics for the expression.</p>
               <p>Some other examples of implausible expressions include:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">round(tokenize($input))</code>. The result of <function>fn:tokenize</function>
               is a sequence of strings (<code nobreak="false">xs:string*</code>), while the required type for the
               first argument of <function>fn:round</function> is optional numeric (<code nobreak="false">xs:numeric?</code>).
               The expression can succeed only in the exceptional case where the result of <function>fn:tokenize</function>
               is the empty sequence, in which case the result of <function>fn:round</function> will also be
               the empty sequence; it is therefore highly likely that the expression was written in error.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">parse-csv($input)?column-names</code>. The signature of the <code nobreak="false">parse-csv</code>
               function declares its return type as <code nobreak="false">record(columns, rows)</code>. There is no field in this
               record named <code nobreak="false">column-names</code>, and therefore the lookup expression will always
               return the empty sequence. Again, there is no good reason that a user would write this,
               so it is likely that it was written in error.</p>
                  </item>
               </ulist>
               <note>
                  <p>The specification is deliberately conservative in the choice of constructs that have
            been classified as implausible. Constructs have not been classified as implausible merely because there
            are better ways of writing the same thing, but only in cases where it is considered that no user in full understanding
            of the specification would intentionally write such a construct. All these cases correspond to situations
            that would be classed as errors in a language with stricter static typing rules.</p>
               </note>
               <note>
                  <p>In many cases the classification of constructs as implausible is designed to protect users
            from usability problems that have been found with earlier versions of the language. without
            introducing backwards incompatibilities.</p>
               </note>
            </div3>
         </div2>
         <div2 id="id-important-concepts">
            <head>Concepts</head>
            <p>This section explains some concepts that are important to the processing of XQuery 4.0 expressions.</p>
            <div3 id="id-document-order">
               <head>Document Order</head>
               <p>An ordering called <term>document order</term> is defined among all the 
               nodes accessible during processing of a given <phrase role="xquery">query</phrase>
               , which may consist of one or more <term>trees</term> (documents or fragments).</p>
               <p>Document order applies both to <termref def="dt-XNode">XNodes</termref> (typically
               corresponding to nodes in an XML document, and generally referred to simply as <term>nodes</term>),
               and also to <termref def="dt-JNode">JNodes</termref>, often corresponding to the contents
               of a JSON source text. These are known collectively as 
               <termref def="dt-GNode">GNodes</termref> (for "generalized node").</p>
               <p>Document order is defined in <xspecref spec="DM40" ref="document-order"/>, and its definition is repeated here for convenience. 

Document order is a total ordering, although the relative order of some nodes is <termref def="dt-implementation-dependent">implementation-dependent</termref>.  

<termdef term="document order" id="dt-document-order">Informally, <term>document order</term> is the order in which nodes appear in the XML serialization of a document.</termdef>
                  <termdef term="stable" id="stable">Document order is <term>stable</term>, which means that the relative order of two nodes will not change during the processing of a given <phrase role="xquery">query</phrase>
                  , even if this order is <termref def="dt-implementation-dependent">implementation-dependent</termref>.</termdef>
                  <termdef term="reverse document order" id="dt-reverse-document-order">The node ordering that is the reverse of document order is called <term>reverse document order</term>.</termdef>
               </p>
               <p>Within an <xtermref spec="DM40" ref="dt-XTree"/>,
               (that is, a tree consisting of XNodes), document order satisfies the following constraints:</p>
               <olist>
                  <item>
                     <p>The root node precedes all other nodes.</p>
                  </item>
                  <item>
                     <p>A parent node precedes its children (and therefore its descendants).</p>
                  </item>
                  <item>
                     <p>The children of a node <var>N</var> precede the following siblings of <var>N</var>.</p>
                  </item>
                  <item>
                     <p>Attribute nodes immediately follow the namespace nodes of the
element node with which they are associated. The relative order of
attribute nodes is stable but <termref def="dt-implementation-dependent">implementation-dependent</termref>.</p>
                  </item>
                  <item>
                     <p>The relative order of siblings is the order in which they occur
in the <code nobreak="false">children</code> property of their parent node.</p>
                  </item>
               </olist>
               <p>Similarly, within an <xtermref spec="DM40" ref="dt-JTree"/>,
               (that is, a tree consisting of JNodes), document order satisfies the following constraints:</p>
               <olist>
                  <item>
                     <p>The root JNode precedes all other JNodes.</p>
                  </item>
                  <item>
                     <p>A parent JNode precedes its children (and therefore its descendants).</p>
                  </item>
                  <item>
                     <p>The children of a JNode <var>N</var> precede the following siblings of <var>N</var>.</p>
                  </item>
                  <item>
                     <p>The children of a JNode that wraps an array follow the ordering of the members of the array.</p>
                  </item>
                  <item>
                     <p>The children of a JNode that wraps a map follow the ordering of the entries in the map.</p>
                  </item>
               </olist>
               <p>The relative order of nodes in distinct trees is stable but
<termref def="dt-implementation-dependent">implementation-dependent</termref>,
subject to the following constraint: If any node in a given tree <var>T1</var> is before
any node in a different tree <var>T2</var>, then all nodes in tree <var>T1</var> are before all nodes in
tree <var>T2</var>.</p>
            </div3>
            <div3 id="id-typed-value">
               <head>Typed Value and String Value</head>
               <p>Every node (that is, every <xtermref spec="DM40" ref="dt-XNode"/>)
               has a <term>typed value</term> and a <term>string value</term>, except for nodes whose value is <xtermref spec="DM40" ref="dt-absent"/>.
               
               <termdef term="typed value" id="dt-typed-value">The <term>typed
                     value</term> of a node is a sequence of atomic items and can be
                  extracted by applying the <function>data</function> function to the
                  node.</termdef>
                  <termdef id="dt-string-value" term="string value">The
                  <term>string value</term> of a node is a string and can be extracted
                  by applying the <function>string</function>
                  function to the node.</termdef>
               </p>
               <p>An implementation may store both the <termref def="dt-typed-value">typed value</termref> and the <termref def="dt-string-value">string value</termref> of a node, or it may store only one of these and derive the other as needed.
               The string value of a node must be a valid lexical representation of the typed value of the node,
               but the node is not required to preserve the string representation from the original source document.
               For example, if the typed value of a node is the <code nobreak="false">xs:integer</code> value <code nobreak="false">30</code>,
               its string value might be <code nobreak="false">"30"</code> or <code nobreak="false">"0030"</code>.</p>
               <p role="xquery">The <termref def="dt-typed-value">typed value</termref>, <termref def="dt-string-value">string value</termref>, and <termref def="dt-type-annotation">type annotation</termref> of a node are closely related, and are defined by rules found in the following locations:</p>
               <ulist role="xquery">
                  <item>
                     <p>If the node was created by mapping from an Infoset or PSVI, see rules in <xspecref spec="DM40" ref="types"/>.</p>
                  </item>
                  <item>
                     <p>If the node was created by an XQuery node constructor, see rules in <specref ref="id-element-constructor"/>, <specref ref="id-computedElements"/>, or <specref ref="id-computedAttributes"/>.</p>
                  </item>
                  <item>
                     <p>If the node was created by a <code nobreak="false">validate</code> expression, see rules in <specref ref="id-validate"/>.</p>
                  </item>
               </ulist>
               <p>The relationship between <termref def="dt-typed-value">typed value</termref> and
               <termref def="dt-string-value">string value</termref> for various kinds of nodes is summarized and illustrated
               by examples below.</p>
               <olist>
                  <item>
                     <p>For text and document nodes, the typed value of the node is the same as its
                     string value, as an instance of  the type <code nobreak="false">xs:untypedAtomic</code>. The
                     string value of a document node is formed by concatenating the string
                     values of all its descendant text nodes, in <termref def="dt-document-order">document
                        order</termref>.</p>
                  </item>
                  <item>
                     <p>The typed value of a comment or processing instruction node is the same as its string value. It is an instance of the type <code nobreak="false">xs:string</code>.</p>
                  </item>
                  <item>
                     <p>The typed value of an attribute node with
                     the <termref def="dt-type-annotation">type annotation</termref>
                        <code nobreak="false">xs:anySimpleType</code> or <code nobreak="false">xs:untypedAtomic</code> is the same as its
                     string value, as an instance of <code nobreak="false">xs:untypedAtomic</code>. The
                     typed value of an attribute node with any other type annotation is
                     derived from its string value and type annotation using the lexical-to-value-space mapping defined in <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/> Part 2 for
                     the relevant type.</p>
                     <p>Example: A1 is an attribute
                     having string value <code nobreak="false">"3.14E-2"</code> and type annotation
                     <code nobreak="false">xs:double</code>.  The typed value of A1 is the
                     <code nobreak="false">xs:double</code> value whose lexical representation is
                     <code nobreak="false">3.14E-2</code>. </p>
                     <p>Example: A2 is an attribute with type
                     annotation <code nobreak="false">xs:IDREFS</code>, which is a list datatype whose item type is the atomic datatype <code nobreak="false">xs:IDREF</code>. Its string value is
                     <code nobreak="false">"bar baz faz"</code>. The typed value of A2 is a sequence of
                     three atomic items (<code nobreak="false">"bar"</code>, <code nobreak="false">"baz"</code>",
                     <code nobreak="false">"faz"</code>"), each of type <code nobreak="false">xs:IDREF</code>. The typed
                     value of a node is never treated as an instance of a named list
                     type. Instead, if the type annotation of a node is a list type (such
                     as <code nobreak="false">xs:IDREFS</code>), its typed value is treated as a sequence
                     of the <termref def="dt-generalized-atomic-type">generalized atomic type</termref> from which it is derived (such as
                     <code nobreak="false">xs:IDREF</code>).</p>
                  </item>
                  <item>
                     <p>For an element node, the
                     relationship between typed value and string value depends on the
                     node’s <termref def="dt-type-annotation">type annotation</termref>, as follows:</p>
                     <olist>
                        <item>
                           <p>If the type annotation is <code nobreak="false">xs:untyped</code> or <code nobreak="false">xs:anySimpleType</code> or
                           denotes a complex type with mixed content (including <code nobreak="false">xs:anyType</code>), then the typed value of the
                           node is equal to its string value, as an instance of
                           <code nobreak="false">xs:untypedAtomic</code>.  However, if the <code nobreak="false">nilled</code>
                           property of the node is <code nobreak="false">true</code>, then its typed value is the empty sequence.</p>
                           <p>Example: E1 is an element node
                           having type annotation <code nobreak="false">xs:untyped</code> and string value
                           <code nobreak="false">"1999-05-31"</code>. The typed value of E1 is
                           <code nobreak="false">"1999-05-31"</code>, as an instance of
                           <code nobreak="false">xs:untypedAtomic</code>.</p>
                           <p>Example: E2 is an element node
                           with the type annotation <code nobreak="false">formula</code>, which is a complex type
                           with mixed content. The content of E2 consists of the character
                           <code nobreak="false">H</code>, a child element named <code nobreak="false">subscript</code> with
                           string value <code nobreak="false">"2"</code>, and the character <code nobreak="false">O</code>. The
                           typed value of E2 is <code nobreak="false">"H2O"</code> as an instance of
                           <code nobreak="false">xs:untypedAtomic</code>.</p>
                        </item>
                        <item>
                           <p>If the type
                           annotation denotes a simple type or a complex type with simple
                           content, then the typed value of the node is derived from its string
                           value and its type annotation in a way that is consistent with schema
                           validation. However, if the <code nobreak="false">nilled</code>
                           property of the node is <code nobreak="false">true</code>, then its typed value is the empty sequence.</p>
                           <p>Example: E3 is an element node with the type
                           annotation <code nobreak="false">cost</code>, which is a complex type that has several
                           attributes and a simple content type of <code nobreak="false">xs:decimal</code>. The
                           string value of E3 is <code nobreak="false">"74.95"</code>. The typed value of E3 is
                           <code nobreak="false">74.95</code>, as an instance of
                           <code nobreak="false">xs:decimal</code>.</p>
                           <p>Example: E4 is an element node with the
                           type annotation <code nobreak="false">hatsizelist</code>, which is a simple type
                           derived from the <termref def="dt-atomic-type"/>
                              <code nobreak="false">hatsize</code>, which in turn is
                           derived from <code nobreak="false">xs:integer</code>. The string value of E4 is
                           <code nobreak="false">"7 8 9"</code>. The typed value of E4 is a sequence of three
                           values (<code nobreak="false">7</code>, <code nobreak="false">8</code>, <code nobreak="false">9</code>), each of type
                           <code nobreak="false">hatsize</code>.</p>
                           <p>Example: E5 is an element node with the type annotation <code nobreak="false">my:integer-or-string</code>
                           which is a union type with member types <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:string</code>.
                           The string value of E5 is <code nobreak="false">"47"</code>. The typed value of E5 is <code nobreak="false">47</code> as a
                           <code nobreak="false">xs:integer</code>, since <code nobreak="false">xs:integer</code> is the member type that validated the
                           content of E5. In general, when the type annotation of a node is a union type,
                           the typed value of the node will be an instance of one of the member types of the union.</p>
                           <note>
                              <p>If an implementation stores only the string value of a node, and the type annotation of the node is a union type, the implementation must be able to deliver the typed value of the node as an instance of the appropriate member type.</p>
                           </note>
                        </item>
                        <item>
                           <p>If the type annotation
                           denotes a complex type with empty content, then the typed value of the
                           node is the empty sequence and its string value is the zero-length string.</p>
                        </item>
                        <item>
                           <p>If the type annotation
                           denotes a complex type with element-only content, then the typed value
                           of the node is <xtermref spec="DM40" ref="dt-absent"/>. The <function>fn:data</function> function raises a
                           <termref def="dt-type-error">type error</termref>
                              <xerrorref spec="FO40" class="TY" code="0012"/> when applied to such a node. The string value of such a node is equal to the concatenated string values of all its text node descendants, in document order.</p>
                           <p>Example: E6 is an
                           element node with the type annotation <code nobreak="false">weather</code>, which is a
                           complex type whose content type specifies
                           <code nobreak="false">element-only</code>. E6 has two child elements named
                           <code nobreak="false">temperature</code> and <code nobreak="false">precipitation</code>. The typed
                           value of E6 is <xtermref spec="DM40" ref="dt-absent"/>, and the <function>fn:data</function> function
                           applied to E6 raises an error.
                        </p>
                        </item>
                     </olist>
                  </item>
               </olist>
            </div3>
            <div3 id="id-atomization">
               <head>Atomization</head>
               <p>The semantics of some
XQuery 4.0 operators depend on a process called <termref def="dt-atomization">atomization</termref>. Atomization is
applied to a value when the value is used in a context in which a
sequence of atomic items is required. The result of atomization is
either a sequence of atomic items or a <termref def="dt-type-error">type error</termref>
                  <xerrorref spec="FO40" class="TY" code="0012"/>.  <termdef id="dt-atomization" term="atomization">
                     <term>Atomization</term> of a sequence
is defined as the result of invoking the <function>fn:data</function> function, as defined in <xspecref spec="FO40" ref="func-data"/>.</termdef>
               </p>
               <p> The semantics of
<function>fn:data</function> are repeated here for convenience. The result of
<function>fn:data</function> is the sequence of atomic items produced by
applying the following rules to each item in the input
sequence:</p>
               <ulist>
                  <item>
                     <p>If the item is an atomic item, it is
returned.</p>
                  </item>
                  <item>
                     <p>If the item is a node (specifically, an <termref def="dt-XNode"/>),
its <termref def="dt-typed-value">typed value</termref> is returned (a <termref def="dt-type-error">type error</termref>
                        <xerrorref spec="FO40" class="TY" code="0012"/> is raised if the node has no typed value.)</p>
                  </item>
                  <item>
                     <p>If the item is a <xtermref spec="DM40" ref="dt-JNode"/>,
                  its <term>·jvalue·</term> property is atomized and the result is returned.</p>
                  </item>
                  <item>
                     <p>If the item is a <termref def="dt-function-item">function item</termref> (other than an array) or map a <termref def="dt-type-error">type error</termref>
                        <xerrorref spec="FO40" class="TY" code="0013"/> is raised.</p>
                  </item>
                  <item>
                     <p>If the item is an array <code nobreak="false">$a</code>, atomization is defined as <code nobreak="false">$a?* ! fn:data(.)</code>, which is equivalent to atomizing the members of the array.</p>
                     <note>
                        <p>This definition recursively atomizes members that are arrays. Hence, the result of atomizing the array <code nobreak="false">[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]</code> is the sequence <code nobreak="false">(1, 2, 3, 4, 5, 6)</code>.</p>
                     </note>
                  </item>
               </ulist>
               <p>Atomization is used in
processing many expressions that are designed to operate on atomic items, including: </p>
               <ulist>
                  <item>
                     <p>Arithmetic expressions</p>
                  </item>
                  <item>
                     <p>Comparison expressions</p>
                  </item>
                  <item>
                     <p>Function calls and returns</p>
                  </item>
                  <item>
                     <p>Cast expressions</p>
                  </item>
                  <item role="xquery">
                     <p>Constructor expressions for various kinds of nodes</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <code nobreak="false">order by</code> clauses in FLWOR expressions</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <code nobreak="false">group by</code> clauses in FLWOR expressions</p>
                  </item>
                  <item role="xquery">
                     <p>Switch expressions</p>
                  </item>
               </ulist>
               <p>Atomization plays an important role in the <termref def="dt-coercion-rules"/> used
            when converting a supplied argument in a function call to the type declared
            in the function signature.</p>
            </div3>
            <div3 id="id-ebv">
               <head>Effective Boolean Value</head>
               <p>Under certain circumstances (some of which are listed below), it is necessary to find
the <termref def="dt-ebv">effective boolean value</termref> of a
value. <termdef id="dt-ebv" term="effective boolean value">The
<term>effective boolean value</term> of a value is defined as the result
of applying the <function>fn:boolean</function> function to the value.</termdef>
               </p>
               <p>The dynamic semantics of <function>fn:boolean</function> are repeated here for convenience:</p>
               <olist>
                  <item>
                     <p>If its operand is the empty sequence, <function>fn:boolean</function> returns <code nobreak="false">false</code>.</p>
                  </item>
                  <item>
                     <p>If its operand is a sequence whose first item is a 
                     <termref def="dt-GNode"/>, <function>fn:boolean</function> returns 
                     <code nobreak="false">true</code>.</p>
                  </item>
                  <item>
                     <p>If its operand is a <termref def="dt-singleton"/> value of 
                     type <code nobreak="false">xs:boolean</code> or derived from <code nobreak="false">xs:boolean</code>, 
                     <function>fn:boolean</function> returns the value of its operand unchanged.</p>
                  </item>
                  <item>
                     <p>If its operand is a <termref def="dt-singleton"/> value of 
                     type <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>, 
                     <code nobreak="false">xs:untypedAtomic</code>, or a type derived from one of these,
                     <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 its operand is a <termref def="dt-singleton"/> value of 
                     any <termref def="dt-numeric"/> type or 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>
                  <item>
                     <p>In all other cases, <function>fn:boolean</function> raises a type error <xerrorref spec="FO40" class="RG" code="0006"/>.</p>
                     <note>
                        <p>For instance, <function>fn:boolean</function> raises a type error if the operand is a function, a map, or an array.</p>
                     </note>
                  </item>
               </olist>
               <p>The <termref def="dt-ebv">effective boolean value</termref> of a sequence is computed implicitly during  processing of the following types of expressions: </p>
               <ulist>
                  <item>
                     <p>Logical expressions (<code nobreak="false">and</code>, <code nobreak="false">or</code>)</p>
                  </item>
                  <item>
                     <p>The <function>fn:not</function> function</p>
                  </item>
                  <item role="xquery">
                     <p>The <code nobreak="false">where</code> clause of a FLWOR expression</p>
                  </item>
                  <item>
                     <p>Certain types of <termref def="dt-predicate">predicates</termref>, such as <code nobreak="false">a[b]</code>
                     </p>
                  </item>
                  <item>
                     <p>Conditional expressions (<code nobreak="false">if</code>)</p>
                  </item>
                  <item>
                     <p>Quantified expressions (<code nobreak="false">some</code>, <code nobreak="false">every</code>)</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt> and <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$spec = xquery40--></nt> in <code nobreak="false">window</code> clauses.</p>
                  </item>
               </ulist>
               <note>
                  <p>The definition of <termref def="dt-ebv">effective boolean
  value</termref> is <emph>not</emph> used when casting a value to the
  type <code nobreak="false">xs:boolean</code>, for example in a <code nobreak="false">cast</code>
  expression. It also plays no role in the <termref def="dt-coercion-rules"/>
  used when passing a value to a function whose signature declares a
  parameter of type <code nobreak="false">xs:boolean</code>.</p>
               </note>
            </div3>
            <div3 id="id-uri-literals">
               <head>URI Literals</head>
               <p>XQuery 4.0 requires a statically known, valid URI in <phrase role="xquery">a <nt def="prod-xquery40-URILiteral">URILiteral<!--$spec = xquery40--></nt> or
      </phrase>a <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$spec = xquery40--></nt>. 

      An implementation may raise a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0046"/> if the value of <phrase role="xquery">a
      URI Literal or</phrase> a Braced URI Literal is of nonzero length
      and is neither an
      absolute URI nor a relative URI.</p>
               <p role="xquery">As in a string literal, any <termref def="dt-predefined-entity-reference">predefined entity
      reference</termref> (such as <code nobreak="false">&amp;amp;</code>), <termref def="dt-character-reference">character reference</termref> (such
      as <code nobreak="false">&amp;#x2022;</code>), or <nt def="prod-xquery40-EscapeQuot">EscapeQuot<!--$spec = xquery40--></nt> or <nt def="prod-xquery40-EscapeApos">EscapeApos<!--$spec = xquery40--></nt> (for example, <code nobreak="false">""</code>)
      is replaced by its appropriate expansion. Certain characters,
      notably the ampersand, can only be represented using a <termref def="dt-predefined-entity-reference">predefined entity
      reference</termref> or a <termref def="dt-character-reference">character reference</termref>.</p>
               <note>
                  <p>The <code nobreak="false">xs:anyURI</code>
      type is designed to anticipate the introduction of
      Internationalized Resource Identifiers (IRIs) as defined in
      <bibref ref="RFC3987"/>.</p>
               </note>
               <p>Whitespace is normalized using the whitespace normalization rules
      of <function>fn:normalize-space</function>. If the result of whitespace
      normalization contains only whitespace, the corresponding URI
      consists of the empty string.  <phrase role="xquery">Whitespace
      normalization is done after the expansion of <termref def="dt-character-reference">character references</termref>, so
      writing a newline (for example) as <code nobreak="false">&amp;#xA;</code> does
      not prevent its being normalized to a space
      character.</phrase>
               </p>
               <p>A Braced URI Literal or URI Literal is not
      subjected to percent-encoding
      or decoding as defined in <bibref ref="RFC3986"/>.</p>
            </div3>
            <div3 id="id-constants">
               <head>Constants</head>
               <p>Some grammatical contexts allow a <nt def="doc-xquery40-Constant">Constant<!--$spec = xquery40--></nt> to appear.
            A constant may be a string or numeric literal, but it also allows negative numbers
            and booleans.</p>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-Constant">
                     <lhs>Constant</lhs>
                     <rhs>
                        <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("-"?  <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>)  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("true"  "("  ")")  |  ("false"  "("  ")")</rhs>
                  </prod>

                  <prod id="doc-xquery40-Constant-StringLiteral">
                     <lhs>StringLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-Constant-NumericLiteral">
                     <lhs>NumericLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BinaryIntegerLiteral">BinaryIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DecimalLiteral">DecimalLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DoubleLiteral">DoubleLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-Constant-QNameLiteral">
                     <lhs>QNameLiteral</lhs>
                     <rhs>"#"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>A constant may take any of the following forms:</p>
               <ulist diff="chg" at="issue637">
                  <item>
                     <p>A string literal, for example <code nobreak="false">"Paris"</code> or <code nobreak="false">'London'</code>, denoting
                 a value of type <code nobreak="false">xs:string</code>.</p>
                  </item>
                  <item>
                     <p>A numeric literal, for example <code nobreak="false">0</code>, <code nobreak="false">0.1</code>, <code nobreak="false">0x7FFF</code>,
                   or <code nobreak="false">1e-6</code>,
                   denoting a value of type <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:integer</code>, 
                   or <code nobreak="false">xs:double</code>. The literal may be preceded by a minus sign to represent a negative
                   number.</p>
                  </item>
                  <item>
                     <p>One of the constructs <code nobreak="false">true()</code> or <code nobreak="false">false()</code>, denoting
                 the <code nobreak="false">xs:boolean</code> values <code nobreak="false">true</code> and <code nobreak="false">false</code> respectively.</p>
                     <note diff="add" at="issue637">
                        <p>The constructs <code nobreak="false">true()</code> and <code nobreak="false">false()</code> must be written as
                  prescribed by the grammar. No namespace prefix is allowed. Although the values resemble calls to
                  functions in the default function namespace, they are unaffected by the namespace
                  context.</p>
                     </note>
                  </item>
                  <item>
                     <p>A QName literal, for example <code nobreak="false">#div</code> or <code nobreak="false">#xml:space</code>, denoting
                 a value of type <code nobreak="false">xs:QName</code>.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-resolve-relative-uri">
               <head>Resolving a Relative URI Reference</head>
               <p>
                  <termdef id="dt-resolve-relative-uri" term="resolve">To
      <term>resolve a relative URI</term>
                     <code nobreak="false">$rel</code> against a
      base URI <code nobreak="false">$base</code> is to expand it to an absolute URI,
      as if by calling the function <code nobreak="false">fn:resolve-uri($rel,
      $base)</code>.</termdef> During static analysis, the base URI is
      the Static Base URI. During dynamic evaluation, the base URI
      used to resolve a relative URI reference depends on the semantics of the
      expression.</p>
               <p>Any process that attempts to <termref def="dt-resolve-relative-uri">resolve a URI</termref> against a
      base URI, or to dereference the URI, may apply percent-encoding
      or decoding as defined in the relevant RFCs.</p>
            </div3>
         </div2>
      </div1>
      <div1 id="id-types">
         <head>Types</head>
         <p>As noted in <specref ref="id-values"/>, every value in XQuery 4.0 is regarded
      as a <termref def="dt-sequence"/> of zero, one, or more <termref def="dt-item">items</termref>.
      The type system of XQuery 4.0, described in this section, classifies the
      kinds of value that the language can handle, and the operations permitted
      on different kinds of value.</p>
         <p>The type system of XQuery 4.0 is related to the type system of
		<bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/> in two ways:</p>
         <ulist>
            <item>
               <p>atomic items in XQuery 4.0 (which are one kind of <termref def="dt-item"/>)
               have <termref def="dt-atomic-type">atomic types</termref> such as <code nobreak="false">xs:string</code>,
               <code nobreak="false">xs:boolean</code>, and <code nobreak="false">xs:integer</code>. These types are taken directly
               from their definitions in <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/>.</p>
            </item>
            <item>
               <p>
                  <termref def="dt-XNode">XNodes</termref> 
               (which are another kind of <termref def="dt-item"/>) have a property
            called a <termref def="dt-type-annotation"/> which determines the type of their content.
            The type annotation is a <termref def="dt-schema-type"/>. The type annotation of a node
            must not be confused with the item type of the node. For example, an element 
            <code nobreak="false">&lt;age&gt;23&lt;/age&gt;</code> might have been validated against a schema
               that defines this element as having <code nobreak="false">xs:integer</code> content. If this
               is the case, the <termref def="dt-type-annotation"/> of the node will be
               <code nobreak="false">xs:integer</code>, and in the XQuery 4.0 type system, the node will
               match the <termref def="dt-item-type"/>
                  <code nobreak="false">element(age, xs:integer)</code>.
            </p>
            </item>
         </ulist>
         <p>This chapter of the specification starts by defining 
            <termref def="dt-sequence-type">sequence types</termref> and 
         <termref def="dt-item-type">item types</termref>, which describe the range of
            <termref def="dt-value">values</termref> that can be bound to variables, used in 
            expressions, or passed to functions. It then describes how these
            relate to <termref def="dt-schema-type">schema types</termref>,
            that is, the simple and complex types defined in an XSD schema.</p>
         <note>
            <p>In many situations the terms <term>item type</term> and 
         <term>sequence type</term> are used interchangeably to refer either to the type itself,
         or to the syntactic construct that designates the type: so in the expression
         <code nobreak="false">$x instance of xs:string*</code>, the construct <code nobreak="false">xs:string*</code>
         uses the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> syntax to designate a
         <termref def="dt-sequence-type"/> whose instances are sequences of strings.
         When more precision is required, the specification is careful to use the terms
         <termref def="dt-item-type"/> and <termref def="dt-sequence-type"/> to
         refer to the actual types, while using the production names <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt>
         and <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> to refer to the syntactic
         designators of these types.</p>
         </note>
         <div2 id="id-sequencetype-syntax">
            <head>Sequence Types</head>
            <p>
               <termdef id="dt-sequence-type" term="sequence type">A <term>sequence type</term> is a type that can be expressed using the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>
                  syntax. Sequence types are used whenever it is necessary to refer to a type in an XQuery 4.0 expression. 
                  Since all values are sequences, every value matches one or more <term>sequence types</term>.</termdef>
            </p>
            <p>Whenever it is necessary to refer to a <term>sequence type</term> 
            in an XQuery 4.0 expression, the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> syntax is used.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-SequenceType">
                  <lhs>SequenceType</lhs>
                  <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
               </prod>

               <prod id="doc-xquery40-SequenceType-ItemType">
                  <lhs>ItemType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-SequenceType-OccurrenceIndicator">
                  <lhs>OccurrenceIndicator</lhs>
                  <rhs>"?"  |  "*"  |  "+"</rhs>
                  <com>
                     <loc href="#parse-note-occurrence-indicators">xgc: occurrence-indicators</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-sequence-type-designator" term="sequence type designator">A
      <term>sequence type designator</term> is a syntactic construct conforming to the grammar rule
         <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>. A sequence type designator is said
      to <term>designate</term> a <termref def="dt-sequence-type"/>.</termdef>
            </p>
            <p>With the exception of the special type
<code nobreak="false">empty-sequence()</code>, a <termref def="dt-sequence-type">sequence type</termref> consists of an
<termref def="dt-item-type"/> that constrains the type of each item in the
sequence, and a <term>cardinality</term> that constrains the number of
items in the sequence. Apart from the item type <code nobreak="false">item()</code>,
which permits any kind of item, item types divide into <term>node
types</term> (such as <code nobreak="false">element()</code>), <term>generalized atomic
types</term> (such as <code nobreak="false">xs:integer</code>) and function types
(such as <code nobreak="false">function() as item()*</code>).</p>
            <p>The cardinality of a <termref def="dt-sequence-type"/> is represented
               in the <termref def="dt-sequence-type-designator"/> syntax by
               an <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$spec = xquery40--></nt>. 
               The occurrence indicators <code nobreak="false">+</code>, <code nobreak="false">*</code>, and <code nobreak="false">?</code> 
               bind to the last <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> in the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>, as described in the <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                    href="#parse-note-occurrence-indicators"
                    xlink:type="simple"
                    xlink:show="replace"
                    xlink:actuate="onRequest">occurrence-indicators</loc> constraint.</p>
            <div3 id="id-sequence-type-examples">
               <head>Examples of Sequence Types</head>
               <p>Here are some examples of <termref def="dt-sequence-type">sequence types</termref> that
		  might be used in XQuery 4.0:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">xs:date</code> refers to the built-in atomic schema type named <code nobreak="false">xs:date</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">attribute()?</code> refers to an optional attribute node</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">element()</code> refers to any element node</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">element(po:shipto, po:address)</code> refers to an element node that has the name <code nobreak="false">po:shipto</code> and has the type annotation <code nobreak="false">po:address</code> (or a schema type derived from <code nobreak="false">po:address</code>)</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">element(*, po:address)</code> refers to an element node of any name that has the type annotation <code nobreak="false">po:address</code> (or a type derived from <code nobreak="false">po:address</code>)</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">element(customer)</code> refers to an element node named <code nobreak="false">customer</code> with any type annotation</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">schema-element(customer)</code> refers to an element node whose name is <code nobreak="false">customer</code> (or is in the substitution group headed by <code nobreak="false">customer</code>) and whose type annotation matches the schema type declared for a <code nobreak="false">customer</code> element in the <termref def="dt-is-elems">in-scope element declarations</termref>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">node()*</code> refers to a sequence of zero or more nodes of any kind</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">item()+</code> refers to a sequence of one or more <termref def="dt-item">items</termref>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">function(*)</code> refers to any <termref def="dt-function-item">function item</termref>, regardless of arity or type</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">function(node()) as xs:string*</code> refers to a <termref def="dt-function-item"/> that takes a single argument whose value is a single node,
        and returns a sequence of zero or more <code nobreak="false">xs:string</code> values</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">(fn(node()) as xs:string)*</code> refers to a sequence of zero or more <termref def="dt-function-item">function items</termref>, each of which takes a single
        argument whose value is a single node, and returns as its result a single <code nobreak="false">xs:string</code> value</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-sequencetype-matching">
               <head>Sequence Type Matching</head>
               <p diff="chg" at="B">
                  <termdef id="dt-sequencetype-matching" term="SequenceType matching">
                     <term>SequenceType matching</term> compares a value with an expected <termref def="dt-sequence-type">sequence type</termref>. </termdef> For example, an <code nobreak="false">instance of</code> expression 
               returns <code nobreak="false">true</code> if a given value matches a given <termref def="dt-sequence-type">sequence type</termref>, and <code nobreak="false">false</code> if it does not.</p>
               <p>An XQuery 4.0 implementation must be able to determine relationships among the types in type annotations in an <termref def="dt-data-model-instance">XDM instance</termref> and the types in the  <termref def="dt-issd">in-scope schema definitions</termref> (ISSD). <phrase role="xquery">An XQuery 4.0 implementation must be able to determine relationships among the types in ISSDs used in different modules of the same query.</phrase>
               </p>
               <p diff="chg" at="B">
                  <termdef term="subtype substitution" id="dt-subtype-substitution">The use of a value that has a <termref def="dt-dynamic-type"/>
                      that is a <termref def="dt-subtype"/> of the
		  expected type is known as <term>subtype substitution</term>.</termdef>
		  Subtype substitution does not change the actual type of a value. For
		  example, if an <code nobreak="false">xs:integer</code> value is used where an
		  <code nobreak="false">xs:decimal</code> value is expected, the value retains its type
		  as <code nobreak="false">xs:integer</code>.</p>
               <!--    <p>The definition of <termref def="dt-sequencetype-matching"
                  >SequenceType matching</termref> relies
		  on a pseudo-function named <code>derives-from(</code>
               <emph>AT</emph>,
		  <emph>ET</emph>
               <code>)</code>, which takes an actual simple or complex
		  schema type <emph>AT</emph> and an expected simple or complex schema
		  type <emph>ET</emph>, and either returns a boolean value or raises a
		  <termref
                  def="dt-type-error">type error</termref>
               <errorref class="TY" code="0004"/>.  This function is defined as follows:</p>

            <ulist>

               <item>
                  <p>
                     <code>derives-from(</code>
                     <emph>AT</emph>, <emph>ET</emph>
                     <code>)</code> raises a type error <errorref class="TY" code="0004"
                        /> if <emph>ET</emph> is
		    not present in the <termref def="dt-issd"
                        >in-scope schema definitions</termref> (ISSD). </p>
               </item>

               <item>
                  <p>
                     <code>derives-from(</code>
                     <emph>AT</emph>,
		    <emph>ET</emph>
                     <code>)</code> returns <code>true</code>  
		    if any of the following conditions applies:

		    <ulist> <item>
                           <p>
                              <emph>AT</emph> is <emph>ET</emph>
                           </p>
                        </item> <item>
                           <p>
                              <emph>ET</emph> is the base type of <emph>AT</emph>
                           </p>
                        </item> <item>
                           <p>
                              <emph>ET</emph> is a pure union type of which <emph>AT</emph> is a member type</p>
                        </item> <item>
                           <p>There is a type <emph>MT</emph> such that <code>derives-from(</code>
                              <emph>AT</emph>, <emph>MT</emph>
                              <code>)</code> 
		      and <code>derives-from(</code>
                              <emph>MT</emph>, <emph>ET</emph>
                              <code>)</code>
                           </p>
                        </item> </ulist>
                  </p>
               </item>

               <item>
                  <p>Otherwise, <code>derives-from(</code>
                     <emph>AT</emph>, <emph>ET</emph>
                     <code>)</code> returns <code>false</code>
                  </p>
               </item>

            </ulist>-->
               <p>The rules for <termref def="dt-sequencetype-matching">SequenceType
		  matching</termref> are given below, with examples (the examples are
		  for purposes of illustration, and do not cover all possible
		  cases).</p>
               <ulist>
                  <item>
                     <p>The <termref def="dt-sequence-type">sequence type</termref>
                        <code nobreak="false">empty-sequence()</code> matches a value that is the empty sequence.</p>
                  </item>
                  <item>
                     <p>An <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> with no <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$spec = xquery40--></nt> matches any value that contains exactly one item if the <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> matches that item (see <specref ref="id-matching-item"/>).</p>
                  </item>
                  <item>
                     <p>An <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> with an <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$spec = xquery40--></nt> matches a value if the number of items in the value matches the <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$spec = xquery40--></nt> and the <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> matches each of the items in the value.</p>
                  </item>
               </ulist>
               <p>An <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$spec = xquery40--></nt> specifies the number of items in
		    a sequence, as follows:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">?</code> matches zero or one items</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">*</code> matches zero or more items</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">+</code> matches one or more items</p>
                  </item>
               </ulist>
               <p>As a consequence of these rules, any <termref def="dt-sequence-type">sequence type</termref> whose
		    <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$spec = xquery40--></nt> is <code nobreak="false">*</code> or <code nobreak="false">?</code> matches a
		    value that is the empty sequence.</p>
            </div3>
            <div3 id="id-schema-type-derivation">
               <head>Schema Type Relationships</head>
               <p>Some <termref def="dt-item-type">item types</termref> are defined in terms
            of <termref def="dt-schema-type">schema types</termref>, and the matching
            rules for such item types depend on the rules defining relationships between
            schema types in the XSD specification.</p>
               <p>
                  <termdef id="dt-derives-from" term="derives from" open="true">A 
               <termref def="dt-schema-type"/>
                     <var>S1</var> is said to <term>derive from</term>
                     <termref def="dt-schema-type"/>
                     <var>S2</var> if any of the following
               conditions is true:</termdef>
               </p>
               <ulist>
                  <item>
                     <p>
                        <var>S1</var> is the same type as <var>S2</var>.</p>
                  </item>
                  <item>
                     <p>
                        <var>S2</var> is the base type of <var>S1</var>.</p>
                  </item>
                  <item>
                     <p>
                        <var>S2</var> is a <termref def="dt-pure-union-type"/>
                     of which <var>S1</var> is a member type.</p>
                  </item>
                  <item>
                     <p>There is a <termref def="dt-schema-type"/>
                        <var>M</var> such that 
                     <var>S1</var>
                        <termref def="dt-derives-from"/>
                        <var>M</var>
                     and <var>M</var>
                        <termref def="dt-derives-from"/>
                        <var>S2</var>.</p>
                  </item>
               </ulist>
               <p role="closetermdef"/>
               <note>
                  <p>The XML Schema specification does not completely specify the circumstances
               under which <var>S1</var> and <var>S2</var> are considered to be the same
               type. For example, if both are anonymous union types with the same member types,
               but defined in different places in the schema, then schema processors have
               discretion whether to treat them as the same type.</p>
               </note>
            </div3>
         </div2>
         <div2 id="id-matching-item">
            <head>Item Types</head>
            <p diff="add" at="B">
               <termdef id="dt-item-type" term="item type">An <term>item type</term> is a type that can be expressed using the <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> syntax, which forms part of the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>
            syntax. Item types match individual <termref def="dt-item">items</termref>.</termdef>
            </p>
            <note>
               <p>While this definition is adequate for the purpose of defining the syntax
            of XQuery 4.0, it ignores the fact that there are also item types that cannot be
            expressed using XQuery 4.0 syntax: specifically, item types that reference
            an anonymous simple type or complex type defined in a schema. Such types 
            can appear as type annotations on nodes following schema validation.</p>
            </note>
            <p>In most cases, the set of items matched by an item type consists either
         exclusively of <termref def="dt-atomic-item">atomic items</termref>,
         exclusively of <termref def="dt-node">nodes</termref>, 
         or exclusively of <xtermref spec="DM40" ref="dt-function-item">function items</xtermref>.
         Exceptions include the generic types <code nobreak="false">item()</code>, which matches all items, <code nobreak="false">xs:error</code>,
         which matches no items, and <termref def="dt-choice-item-type">choice item types</termref>,
         which can match any combination of types.
      </p>
            <p>
               <termdef id="dt-item-type-designator" term="item type designator">An
         <term>item type designator</term> is a syntactic construct conforming to the grammar rule
         <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt>. An item type designator is said
         to <term>designate</term> an <termref def="dt-item-type"/>.</termdef>
            </p>
            <note>
               <p>Two <termref def="dt-item-type-designator">item type designators</termref> may designate the
      same item type. For example, <code nobreak="false">element()</code> and <code nobreak="false">element(*)</code> are equivalent,
      as are <code nobreak="false">attribute(A)</code> and <code nobreak="false">attribute(A, xs:anySimpleType)</code>.</p>
            </note>
            <p>
               <termref def="dt-qname">Lexical QNames</termref> appearing in an <termref def="dt-item-type-designator"/>
               <phrase role="xquery">(other than within
                  a <termref def="dt-function-assertion"/>)</phrase> are expanded using the 
                  <termref def="dt-default-type-namespace-rule"/>.
      Equality of QNames is defined by the <code nobreak="false">eq</code> operator.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ItemType">
                  <lhs>ItemType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-RegularItemType">
                  <lhs>RegularItemType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AnyItemType">AnyItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-XNodeType">XNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-GNodeType">GNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-JNodeType">JNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MapType">MapType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArrayType">ArrayType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-RecordType">RecordType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EnumerationType">EnumerationType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-AnyItemType">
                  <lhs>AnyItemType</lhs>
                  <rhs>"item"  "("  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-XNodeType">
                  <lhs>XNodeType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-DocumentNodeType">DocumentNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ElementNodeType">ElementNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="doc-xquery40-AttributeNodeType">AttributeNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SchemaElementNodeType">SchemaElementNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SchemaAttributeNodeType">SchemaAttributeNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ProcessingInstructionNodeType">ProcessingInstructionNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CommentNodeType">CommentNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TextNodeType">TextNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-NamespaceNodeType">NamespaceNodeType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-AnyXNodeType">AnyXNodeType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-DocumentNodeType">
                  <lhs>DocumentNodeType</lhs>
                  <rhs>"document-node"  "("  (<nt def="prod-xquery40-ElementNodeType">ElementNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SchemaElementNodeType">SchemaElementNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-ElementNodeType">
                  <lhs>ElementNodeType</lhs>
                  <rhs>"element"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  "?"?)?)?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-SchemaElementNodeType">
                  <lhs>SchemaElementNodeType</lhs>
                  <rhs>"schema-element"  "("  <nt def="prod-xquery40-ElementName">ElementName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-NameTestUnion">
                  <lhs>NameTestUnion</lhs>
                  <rhs>(<nt def="prod-xquery40-NameTest">NameTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-NameTest">
                  <lhs>NameTest</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-AttributeNodeType">
                  <lhs>AttributeNodeType</lhs>
                  <rhs>"attribute"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-SchemaAttributeNodeType">
                  <lhs>SchemaAttributeNodeType</lhs>
                  <rhs>"schema-attribute"  "("  <nt def="prod-xquery40-AttributeName">AttributeName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-ProcessingInstructionNodeType">
                  <lhs>ProcessingInstructionNodeType</lhs>
                  <rhs>"processing-instruction"  "("  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-ItemType-CommentNodeType">
                  <lhs>CommentNodeType</lhs>
                  <rhs>"comment"  "("  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-TextNodeType">
                  <lhs>TextNodeType</lhs>
                  <rhs>"text"  "("  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-NamespaceNodeType">
                  <lhs>NamespaceNodeType</lhs>
                  <rhs>"namespace-node"  "("  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-AnyXNodeType">
                  <lhs>AnyXNodeType</lhs>
                  <rhs>"node"  "("  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-GNodeType">
                  <lhs>GNodeType</lhs>
                  <rhs>"gnode"  "("  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-JNodeType">
                  <lhs>JNodeType</lhs>
                  <rhs>"jnode"  "("  (("*"  |  <nt def="prod-xquery40-JRootSelector">JRootSelector<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt>)  (","  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-MapType">
                  <lhs>MapType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AnyMapType">AnyMapType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypedMapType">TypedMapType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-ArrayType">
                  <lhs>ArrayType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AnyArrayType">AnyArrayType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypedArrayType">TypedArrayType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-RecordType">
                  <lhs>RecordType</lhs>
                  <rhs>"record"  "("  (<nt def="prod-xquery40-FieldDeclaration">FieldDeclaration<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-EnumerationType">
                  <lhs>EnumerationType</lhs>
                  <rhs>"enum"  "("  (<nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-FunctionType">
                  <lhs>FunctionType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  (<nt def="prod-xquery40-AnyFunctionType">AnyFunctionType<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$idref_lang_part = xquery40- --></nt>)</rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-TypeName">
                  <lhs>TypeName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemType-ChoiceItemType">
                  <lhs>ChoiceItemType</lhs>
                  <rhs>"("  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt> ++ "|")  ")"</rhs>
               </prod>
            </scrap>
            <p>This section defines the syntax and semantics of different <code nobreak="false">ItemTypes</code>
               in terms of the values that they match.</p>
            <note>
               <p>For an explanation of the EBNF grammar notation (and in particular, the operators
               <code nobreak="false">++</code> and <code nobreak="false">**</code>), see <specref ref="id-grammar"/>.</p>
            </note>
            <p diff="add" at="A">An <termref def="dt-item-type-designator"/> written simply 
               as an <code nobreak="false">EQName</code>
               (that is, a <code nobreak="false">TypeName</code>) is interpreted as follows:</p>
            <olist diff="add" at="A">
               <item>
                  <p>If the name is written as a lexical QName, then it is expanded using the
               <termref def="dt-default-type-namespace-rule"/>.</p>
               </item>
               <item>
                  <p>If the expanded name matches a <termref def="dt-named-item-type"/> in the <termref def="dt-static-context"/>,
                  then it is taken as a reference to the corresponding item type. The rules that
               apply are the rules for the expanded item type definition.</p>
               </item>
               <item>
                  <p>Otherwise, it must match the name of a type in the <termref def="dt-is-types">in-scope schema types</termref>
                  in the <termref def="dt-static-context"/>: specifically, an <termref def="dt-atomic-type"/>
                  or a <termref def="dt-pure-union-type"/>.
                  See <specref ref="id-predefined-types"/> for details.
                  </p>
                  <note>
                     <p>A name in the <code nobreak="false">xs</code> namespace will always fall into this category, since the namespace
               is reserved. See <specref ref="id-namespaces-and-qnames"/>.</p>
                  </note>
               </item>
               <item>
                  <p>If the name cannot be resolved to a type, a <termref def="dt-static-error">static error</termref> 
                  is raised <errorref class="ST" code="0051"/>.</p>
               </item>
            </olist>
            <div3 id="general-item-types">
               <head>General item types</head>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">item()</code> matches
                        any single <termref def="dt-item">item</termref>.</p>
                     <p>For example, <code nobreak="false">item()</code> matches the atomic
                        item <code nobreak="false">1</code>, the element <code nobreak="false">&lt;a/&gt;</code>, or the function <function>fn:concat#3</function>.</p>
                  </item>
                  <item>
                     <p>A <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$spec = xquery40--></nt> lists a number of alternative item types in parentheses,
                        separated by <code nobreak="false">"|"</code>. An item matches a <code nobreak="false">ChoiceItemType</code>
                        it if matches any of the alternatives.</p>
                     <p>For example, <code nobreak="false">(map(*) | array(*))</code> matches any item that
                     is a map or an array.</p>
                     <note>
                        <p>If there is only one alternative, the <code nobreak="false">ChoiceItemType</code>
                         designates the same <termref def="dt-item-type"/>
                         as the <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> that is in parentheses.
                         A singleton choice (that is, a parenthesized item type) is used primarily 
                         when defining nested item types in a function
                      signature. For example, a sequence of functions that each return a single boolean might be denoted
                      <code nobreak="false">(fn() as xs:boolean)*</code>. In this example the parentheses
                      are needed to indicate where the occurrence indicator belongs.</p>
                     </note>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-atomic-types">
               <head>Atomic Types</head>
               <p>Atomic types in the XQuery 4.0 type system correspond directly to atomic types
                  as defined in the <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/>
                 type system.</p>
               <p>Atomic types are either built-in atomic types such as <code nobreak="false">xs:integer</code>,
               or user-defined atomic types imported from a schema. Atomic types are identified
               by a QName: see <specref ref="id-namespaces-and-qnames"/>.</p>
               <note>
                  <p>A schema may also include anonymous atomic types. Such types are
               not usable directly in XQuery 4.0, though they may appear as the values
               of <termref def="dt-type-annotation">type annotations</termref> on nodes.</p>
               </note>
               <p>
                  <termdef id="dt-generalized-atomic-type" term="generalized atomic type">A <term>generalized atomic type</term> is an 
                        <termref def="dt-item-type"/> whose instances are all
                        atomic items. Generalized atomic types include (a) 
                        <termref def="dt-atomic-type">atomic types</termref>, either built-in
                        (for example <code nobreak="false">xs:integer</code>) or imported from a schema, 
                        (b) <termref def="dt-pure-union-type">pure union types</termref>, either built-in
                        (<code nobreak="false">xs:numeric</code> and <code nobreak="false">xs:error</code>) or imported from a schema,
                        (c) <termref def="dt-choice-item-type">choice item types</termref> if their alternatives
                        are all generalized atomic types, and 
                        (d) <termref def="dt-enumeration-type">enumeration types</termref>.
                     </termdef>.</p>
               <!-- <p>
                     <termref def="dt-atomic-type">Atomic types</termref>
                     and <termref def="dt-pure-union-type">pure union types</termref>
                     are usable both as <termref def="dt-schema-type">schema types</termref>
                     and as <termref def="dt-item-type">item types</termref>.</p>-->
               <p>A <termref def="dt-generalized-atomic-type"/> may be designated by 
                     an <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> in any of the following ways:</p>
               <ulist>
                  <item>
                     <p>Using the QName of a type in the <termref def="dt-issd"/> that is an 
                        <termref def="dt-atomic-type"/>
                     or a <termref def="dt-pure-union-type"/>.</p>
                  </item>
                  <item>
                     <p>Using a QName that identifies a <termref def="dt-named-item-type"/> that resolves
                        to a <termref def="dt-generalized-atomic-type"/>.</p>
                  </item>
                  <item>
                     <p>Using a <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$spec = xquery40--></nt> where every alternative
                        is itself a <termref def="dt-generalized-atomic-type"/>.</p>
                  </item>
                  <!--<item><p>Using a <nt def="LocalUnionType">LocalUnionType</nt> as described below.</p></item>-->
                  <item>
                     <p>Using an <nt def="doc-xquery40-EnumerationType">EnumerationType<!--$spec = xquery40--></nt> as described below.</p>
                  </item>
               </ulist>
               <p diff="add" at="2023-02-20">An atomic item <var>A</var> matches the 
                     <termref def="dt-generalized-atomic-type"/>
                  <var>GAT</var> 
                     if the <termref def="dt-type-annotation">type annotation</termref> of <var>A</var>
                  <termref def="dt-derives-from"/>
                  <var>GAT</var>.</p>
               <p>Example: The <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt>
                  <code nobreak="false">xs:decimal</code> matches any value of type
    <code nobreak="false">xs:decimal</code>.  It also matches any value of type
                        <code nobreak="false">shoesize</code>, if <code nobreak="false">shoesize</code> is an <termref def="dt-atomic-type"/>
    derived by restriction from <code nobreak="false">xs:decimal</code>.</p>
               <p>Example: Suppose <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt>
                  <code nobreak="false">dress-size</code> is a union type that allows
    either <code nobreak="false">xs:decimal</code> values for numeric sizes (for example: 4, 6, 10, 12),
    or one of an enumerated set of <code nobreak="false">xs:strings</code>
    (for example: <code nobreak="false">small</code>, <code nobreak="false">medium</code>, <code nobreak="false">large</code>). The <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt>
                  <code nobreak="false">dress-size</code> matches any of these values.</p>
               <note>
                  <p>The names of <phrase diff="chg" at="A">list</phrase>
    types such as <code nobreak="false">xs:IDREFS</code> are not accepted in this context,
    but can often be replaced by a <termref def="dt-generalized-atomic-type">generalized atomic type</termref> with an occurrence indicator, such as
    <code nobreak="false">xs:IDREF+</code>.</p>
               </note>
            </div3>
            <div3 id="id-union-types">
               <head>Union Types</head>
               <p>Union types, as defined in XSD, are a variety of simple types. The membership of
                  a union type in XSD may include list types as well as atomic types and other union types.</p>
               <p>
                  <termdef id="dt-pure-union-type" term="pure union type">A <term>pure union type</term> is a <phrase diff="chg" at="2023-02-20">
                        <term>simple type</term>
                     </phrase> 
                     that satisfies the following constraints:
                     (a) <xtermref spec="XS11-1" ref="std-variety">{variety}</xtermref> is <code nobreak="false">union</code>, 
                     (b) the <xtermref spec="XS11-1" ref="std-facets">{facets}</xtermref> property is empty, 
                     (c) no type in the transitive membership of the union type has 
                     <xtermref spec="XS11-1" ref="std-variety">{variety}</xtermref>
                     <code nobreak="false">list</code>, and 
                     (d) no type in the transitive membership of the union type is a type with 
                     <xtermref spec="XS11-1" ref="std-variety">{variety}</xtermref>
                     <code nobreak="false">union</code> having a non-empty <xtermref spec="XS11-1" ref="std-facets">{facets}</xtermref> property</termdef>.</p>
               <note>
                  <p>The definition of <termref def="dt-pure-union-type">pure union type</termref>
                     excludes union types derived by non-trivial restriction from other
                     union types, as well as union types that include list types in their
                     membership. Pure union types have the property that every
                     instance of an <termref def="dt-atomic-type"/> defined as one of the member types of the
                     union is also a valid instance of the union type.</p>
               </note>
               <note>
                  <p>The current (second) edition of XML Schema 1.0 contains an
                     error in respect of the substitutability of a union type by one of its
                     members: it fails to recognize that this is unsafe if the union is
                     derived by restriction from another union.</p>
                  <p>This problem is fixed in XSD 1.1, but the effect of the resolution
                     is that an atomic item labeled with an atomic type cannot be treated
                     as being substitutable for a union type without explicit validation.
                     This specification therefore allows union types to be used as item
                     types only if they are defined directly as the union of a number of
                     atomic types.</p>
               </note>
               <note>
                  <p>Local union types (see <specref ref="id-choice-item-types"/>) and 
                  <termref def="dt-enumeration-type">enumeration types</termref> cannot be
                  used as the target for schema validation.</p>
               </note>
               <p>
                  <termdef id="dt-numeric" term="numeric">The type <code nobreak="false">xs:numeric</code>
               is defined as a union type with member types <code nobreak="false">xs:double</code>, 
               <code nobreak="false">xs:float</code>, and <code nobreak="false">xs:decimal</code>. An item that
               is an instance of any of these types is referred to as a <term>numeric value</term>,
               and a type that is a subtype of <code nobreak="false">xs:numeric</code> is referred to
               as a <term>numeric type</term>.</termdef>
               </p>
            </div3>
            <div3 id="id-namespace-sensitive">
               <head>Namespace-sensitive Types</head>
               <p>
                  <termdef term="namespace-sensitive" id="dt-namespace-sensitive">The <term>namespace-sensitive</term>
                     types are <code nobreak="false">xs:QName</code>, <code nobreak="false">xs:NOTATION</code>, types
                     derived by restriction from <code nobreak="false">xs:QName</code> or
                     <code nobreak="false">xs:NOTATION</code>, list types that have a namespace-sensitive
                     item type, and union types with a namespace-sensitive type in their
                     transitive membership.</termdef>
               </p>
               <p>It is not possible to preserve the type of a <termref def="dt-namespace-sensitive">namespace-sensitive</termref> value without also preserving the <termref def="dt-namespace-binding"/> 
                  that defines the meaning of each namespace prefix used in the value. Therefore, XQuery 4.0 defines 
                  some error conditions that occur only with <termref def="dt-namespace-sensitive">namespace-sensitive</termref> values. For instance, casting to a <termref def="dt-namespace-sensitive">namespace-sensitive</termref> type raises 
                  a <termref def="dt-type-error">type error</termref>
                  <xerrorref spec="FO40" class="NS" code="0004"/> if the namespace bindings for the result cannot be determined. </p>
            </div3>
            <div3 id="id-choice-item-types">
               <head>Choice Item Types</head>
               <changes>
                  <change issue="122" PR="1132" date="2024-04-09">
                     Choice item types (an item type allowing a set of alternative item types)
                     are introduced.
                  </change>
               </changes>
               <p>
                  <termdef id="dt-choice-item-type" term="choice item type">A 
                  <term>choice item type</term> defines an item type that is the union
               of a number of alternatives. For example the type 
               <code nobreak="false">(xs:hexBinary | xs:base64Binary)</code> defines the union of 
                  these two primitive <termref def="dt-atomic-type">atomic types</termref>, 
                  while the type <code nobreak="false">(map(*) | array(*))</code>
               matches any item that is either a map or an array.</termdef>
               </p>
               <p>An item matches a <code nobreak="false">ChoiceItemType</code> if it matches any of the 
                  alternatives listed within the parentheses.</p>
               <p>For example, the type <code nobreak="false">(xs:NCName | enum(""))</code> matches any value that is either
                  an instance of <code nobreak="false">xs:NCName</code>, or a zero-length string. This might be a suitable type for
                  a variable that holds a namespace prefix.</p>
               <p>If all the alternatives are <termref def="dt-generalized-atomic-type">generalized atomic types</termref>
                  then the <termref def="dt-choice-item-type"/> is itself a generalized atomic type,
               which means, for example, that it can be used as the target of a cast expression.</p>
               <note>
                  <p>A <termref def="dt-choice-item-type"/> in which all the alternatives are atomic
                  behaves in most respects like a schema-defined <termref def="dt-pure-union-type"/>.
                     However, because it can be defined at the point of use (for example,
                     within a function signature), it may be more convenient than defining the type in an
                     imported schema.</p>
               </note>
               <note>
                  <p>Choice item types are particularly useful in function signatures, 
                     allowing a function to take arguments
                  of a variety of types. If the choice item type is a local union type, 
                  then the semantics are identical to using a named union type, but a local union type is more
                  convenient because it does not need to be defined in a schema, and does not require a schema-aware processor.</p>
                  <p>A local union type can also be used in a cast expression: <code nobreak="false">cast @when as (xs:date | xs:dateTime)</code>
                  allows the attribute <code nobreak="false">@when</code> to be either an <code nobreak="false">xs:date</code>, or an <code nobreak="false">xs:dateTime</code>.</p>
                  <p>An <code nobreak="false">instance of</code> expression can be used to test whether a value belongs to one
                  of a number of specified types: <code nobreak="false">$x instance of (xs:string | xs:anyURI | xs:untypedAtomic)</code>
                  returns <code nobreak="false">true</code> if <code nobreak="false">$x</code> is an instance of any of these three atomic types,
                  while <code nobreak="false">$x instance of (map(*) | array(*))</code> tests whether <code nobreak="false">$x</code> is
                  a map or array.</p>
               </note>
            </div3>
            <div3 id="id-enumeration-types" diff="add" at="A">
               <head>Enumeration Types</head>
               <changes>
                  <change issue="688 2152" PR="691 2154" date="2023-10-10">Enumeration types are added as a new kind of <code nobreak="false">ItemType</code>, constraining
                     the value space of strings.</change>
               </changes>
               <p>
                  <termdef id="dt-enumeration-type" term="enumeration type">An <term>EnumerationType</term>
                  accepts a fixed set of string values.</termdef>
               </p>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-EnumerationType">
                     <lhs>EnumerationType</lhs>
                     <rhs>"enum"  "("  (<nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-EnumerationType-StringLiteral">
                     <lhs>StringLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>
               </scrap>
               <p>An <termref def="dt-enumeration-type"/> has a value space consisting of a set of <code nobreak="false">xs:string</code>
                  values. When matching strings against an enumeration type, strings are always compared
               using the Unicode codepoint collation.</p>
               <p>For example, if an argument of a function declares the required type 
                  as <code nobreak="false">enum("red", "green", "blue")</code>, then the string <code nobreak="false">"green"</code> is accepted,
                  while <code nobreak="false">"yellow"</code> is rejected with a type error.</p>
               <p>Technically, enumeration types are defined as follows:</p>
               <ulist>
                  <item>
                     <p>
                        <termdef id="dt-singleton-enumeration-type" term="singleton enumeration type">An 
                     enumeration type with a single enumerated value <var>E</var> (such as
                     <code nobreak="false">enum("red")</code>) matches an item <var>S</var> if and only if (a) <var>S</var>
                     is an instance of <code nobreak="false">xs:string</code>, and (b) <var>S</var> is equal
                     to <var>E</var> when compared using Unicode codepoint collation. This is referred to
                     as a <term>singleton enumeration type</term>.</termdef>
                     </p>
                     <note>
                        <p>When matching a string <var>S</var> against an enumeration type,
                     then apart from the requirement that <var>S</var> is an instance of
                     <code nobreak="false">xs:string</code>, the type annotation of <var>S</var> is immaterial.</p>
                     </note>
                  </item>
                  <item>
                     <p>A <termref def="dt-singleton-enumeration-type"/> whose enumerated value
                  is <var>E</var> is a subtype of <code nobreak="false">xs:string</code>.</p>
                  </item>
                  <item>
                     <p>Two <termref def="dt-singleton-enumeration-type">singleton enumeration types</termref> 
                     are the same type if and only
                  if they have the same (single) enumerated value, as determined using the Unicode
                  codepoint collation.</p>
                  </item>
                  <item>
                     <p>An enumeration type with multiple
                     enumerated values is a union of <termref def="dt-singleton-enumeration-type">singleton enumeration types</termref>, 
                     so <code nobreak="false">enum("red", "green", "blue")</code>
                     is equivalent to <code nobreak="false">(enum("red") | enum("green") | enum("blue"))</code>.</p>
                  </item>
                  <item>
                     <p>In consequence, an enumeration type <var>T</var> is a subtype
                  of an enumeration type <var>U</var> if the enumerated values of <var>T</var>
                  are a subset of the enumerated values of <var>U</var>: 
                     see <specref ref="id-itemtype-subtype"/>.</p>
                  </item>
               </ulist>
               <p>An enumeration type is a <termref def="dt-generalized-atomic-type"/>.</p>
               <p>It follows from these rules that the expression <code nobreak="false">"red" instance of enum("red", "green", "blue")</code>
               returns <code nobreak="false">true</code>. By contrast, <code nobreak="false">xs:untypedAtomic("red") 
                  instance of enum("red", "green", "blue")</code> returns false; but the
                  <termref def="dt-coercion-rules"/> ensure that where a variable
               or function declaration specifies an enumeration type as the required type, 
               an <code nobreak="false">xs:untypedAtomic</code> or <code nobreak="false">xs:anyURI</code> value equal
               to one of the enumerated values will be accepted.</p>
               <note>
                  <p>Some consequences of these rules may not be immediately apparent.</p>
                  <p>Suppose that an XQuery query contains the declarations:</p>
                  <eg xml:space="preserve">
declare type my:color := enum("red", "green", "orange");
declare type my:fruit := enum("apple", "orange", "banana");
declare variable $orange-color as my:color := "orange";
declare variable $orange-fruit as my:fruit := "orange";
                  </eg>
                  <p>The same applies with the equivalent XSLT syntax:</p>
                  <eg xml:space="preserve">
&lt;xsl:item-type name="my:color" as="enum('red', 'green', 'orange')"/&gt;
&lt;xsl:item-type name="my:fruit" as="enum('apple', 'orange', 'banana')"/&gt;
&lt;xsl:variable name="orange-color" as="my:color" select="'orange'"/&gt;
&lt;xsl:variable name="orange-fruit" as="my:fruit" select="'orange'"/&gt;
                     </eg>
                  <p>Now, the value of <code nobreak="false">$orange-color</code> is an atomic item whose datum
                  is the string <code nobreak="false">"orange"</code>, and whose type annotation is <code nobreak="false">xs:string</code>. 
                     Similarly, the value of 
                     <code nobreak="false">$orange-fruit</code> is an atomic item whose datum
                  is the string <code nobreak="false">"orange"</code>, and whose type annotation is <code nobreak="false">xs:string</code>. That is, the values of the two
                     variables are indistinguishable and interchangeable in every way. In particular,
                  both values are instances of <code nobreak="false">my:color</code>,
                  and both are instances of <code nobreak="false">my:fruit</code>.</p>
                  <p>This way of handling enumeration values has advantages and disadvantages.
                  On the positive side, it means that enumeration subsets and supersets work
                  cleanly: a value that is an instance of <code nobreak="false">enum("red", "green", "orange")</code>
                  can be used where an instance of <code nobreak="false">enum("red", "orange", "yellow", "green", "blue", "indigo",
                     "violet")</code> is expected. The downside is that labeling a string as an instance
                  of an enumeration type does not provide type safety: a function that expects an instance
                  of <code nobreak="false">my:color</code> can be called with any string that matches one of the required
                  colors, whether or not it has an appropriate type annotation. A function that expects a color
                  can be successfully called passing a fruit, if they happen to have the same name.</p>
                  <p>In the terminology of computer science, XDM atomic types derived by restriction
                  are <emph>nominative</emph> types, allowing two types with identical properties
                  but different names to be treated as different types with different instances. By
                  contrast, enumeration types are <emph>structural</emph> types, where membership
                  of the type is determined purely by a predicate applied to the value.</p>
                  <p>In consequence, instances of an enumeration type are not annotated as such.
                  The type annotation of such an instance may be <code nobreak="false">xs:string</code> or any type
                  derived by restriction from <code nobreak="false">xs:string</code>, but it will not be the
                  enumeration type itself, which is anonymous.</p>
               </note>
            </div3>
            <div3 id="node-types">
               <head>Node Types</head>
               <changes>
                  <change issue="107" PR="286" date="2023-01-17">
                     Element and attribute tests can include alternative names: <code nobreak="false">element(chapter|section)</code>,
                     <code nobreak="false">attribute(role|class)</code>.
                  </change>
                  <change issue="107" PR="286" date="2023-01-17">
                     The <code nobreak="false">NodeTest</code> in an <code nobreak="false">AxisStep</code> now allows alternatives: 
                     <code nobreak="false">ancestor::(section|appendix)</code>
                  </change>
                  <change issue="1593" date="2024-11-24">
                     The syntax <code nobreak="false">document-node(<var>N</var>)</code>, where <var>N</var> is a <code nobreak="false">NameTestUnion</code>,
                     is introduced as an abbreviation for <code nobreak="false">document-node(element(<var>N</var>))</code>. For example,
                     <code nobreak="false">document-node(*)</code> matches any well-formed XML document (as distinct from a document fragment).
                  </change>
               </changes>
               <p>Node types are <termref def="dt-item-type">item types</termref> whose 
                  instances are all <termref def="dt-node">nodes</termref>.</p>
               <p>The syntax for node types is also used for <termref def="dt-node-test">node tests</termref>
               within path expressions. This explains why the production rules have names such as
               <code nobreak="false">NodeTest</code> rather than <code nobreak="false">NodeType</code>.</p>
               <p>Some of the constructs described in this section include a <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt>. This appears 
                  as <var>T</var> in:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">element(N, T)</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">attribute(N, T)</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">document-node(element(N, T))</code>
                     </p>
                  </item>
               </ulist>
               <p>The type name <var>T</var> is expanded using the <termref def="dt-default-type-namespace-rule"/>. The resulting
               <termref def="dt-expanded-qname"/> must identify a type in the <termref def="dt-issd"/>. This can be any <termref def="dt-schema-type"/>: either a simple type,
               or (except in the case of attributes) a complex type. If it is a simple type then it can be an atomic, union, or
               list type. It can be a built-in type (such as <code nobreak="false">xs:integer</code>) or a user-defined type. It must however
               be the name of a type defined in a schema; it cannot be a <termref def="dt-named-item-type"/>.</p>
               <div4 id="id-simple-node-tests">
                  <head>Simple Node Types</head>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">node()</code>
    matches any node.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">text()</code> matches any
    text node.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">processing-instruction()</code>
    matches any processing instruction
    node.</p>
                     </item>
                     <item>
                        <p at="XQ.E27 and XP.E19">
                           <code nobreak="false">processing-instruction(</code>
                           <emph>N</emph>
                           <code nobreak="false">)</code>
    matches any processing instruction node whose PITarget is equal to <code role="parse-test" nobreak="false">fn:normalize-space(N)</code>. If the result of <code nobreak="false">fn:normalize-space(N)</code> is not in the lexical space of NCName, a type error is raised <errorref class="TY" code="0004"/>
                        </p>
                        <p>Example:
    <code role="parse-test" nobreak="false">processing-instruction(xml-stylesheet)</code> matches any
    processing instruction whose PITarget is
    <code nobreak="false">xml-stylesheet</code>.</p>
                        <p>For backward compatibility with
    XPath 1.0, the PITarget of a
    processing instruction may also be expressed as a
    string literal, as in this example:
    <code role="parse-test" nobreak="false">processing-instruction("xml-stylesheet")</code>.</p>
                        <p>If the specified PITarget is not a syntactically valid NCName, a type error is raised <errorref class="TY" code="0004"/>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">comment()</code> matches any comment node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">namespace-node()</code> matches any
    namespace node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">document-node()</code> matches any document
    node.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">document-node(</code>
                           <emph>E</emph>
                           <code nobreak="false">)</code>, where <var>E</var> is an <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt> or <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt> (see <specref ref="id-element-test"/> and <specref ref="id-schema-element-test"/>)
    matches any document node whose children comprise (in any order) zero or more
    comment and processing instruction nodes, zero text nodes, and exactly one element node,
    which itself must match <var>E</var>.</p>
                        <p>Example:
    <code role="parse-test" nobreak="false">document-node(element(book))</code> matches a document node
    containing
    exactly one element node that is matched by the <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>
                           <code role="parse-test" nobreak="false">element(book)</code>.</p>
                     </item>
                     <item>
                        <p>The construct <code nobreak="false">document-node(<var>NTU</var>)</code>, where
                  <var>NTU</var> is a <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$spec = xquery40--></nt>, is
                  an abbreviation for <code nobreak="false">document-node(element(<var>NTU</var>))</code>.
                  For example, <code nobreak="false">document-node(*)</code> is an abbreviation for
                  <code nobreak="false">document-node(element(*))</code>, which matches any document node
                  corresponding to a well-formed XML document, that is, one that has
                  one element child, zero or more comment and processing instruction children,
                  and no text node children.</p>
                     </item>
                     <item>
                        <p>An <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> that is an
                     <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>, <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt>, 
                        <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt>,
                     <nt def="doc-xquery40-SchemaAttributeNodeType"><!--$spec = xquery40--></nt>, or <nt def="doc-xquery40-FunctionType"><!--$spec = xquery40--></nt> 
                        matches an item as described in the following sections.
                     </p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-element-test">
                  <head>Element Types</head>
                  <changes>
                     <change issue="107" PR="286" date="2023-01-17">
                     Element and attribute tests of the form <code nobreak="false">element(N)</code>
                     and <code nobreak="false">attribute(N)</code> now allow <code nobreak="false">N</code> to be any <code nobreak="false">NameTest</code>,
                     including a wildcard.
                  </change>
                     <change issue="23" PR="606" date="2023-01-17">
                     Element and attribute tests of the form <code nobreak="false">element(A|B)</code>
                     and <code nobreak="false">attribute(A|B)</code> are now allowed.
                  </change>
                     <change>
                     Setting the default namespace for elements and types to the special value
                     <code nobreak="false">##any</code> causes an unprefixed element name to act as a wildcard,
                     matching by local name regardless of namespace.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-ElementNodeType">
                        <lhs>ElementNodeType</lhs>
                        <rhs>"element"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  "?"?)?)?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-ElementNodeType-NameTestUnion">
                        <lhs>NameTestUnion</lhs>
                        <rhs>(<nt def="prod-xquery40-NameTest">NameTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")</rhs>
                     </prod>

                     <prod id="doc-xquery40-ElementNodeType-NameTest">
                        <lhs>NameTest</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-ElementNodeType-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-ElementNodeType-Wildcard">
                        <lhs>Wildcard</lhs>
                        <rhs>"*"<br/>|  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":*")<br/>|  ("*:"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>)<br/>|  (<nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  "*")</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-ElementNodeType-TypeName">
                        <lhs>TypeName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>
                  </scrap>
                  <p>
    An <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt> is used to match an
    element node by its name and/or <termref def="dt-type-annotation">type annotation</termref>.
  </p>
                  <p diff="chg" at="Issue372">An unprefixed <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt>
                  within the <code nobreak="false">NameTestUnion</code> is expanded using the
                  <termref def="dt-element-name-matching-rule"/>.
                  The name need not be present in the <termref def="dt-is-attrs">in-scope element declarations</termref>.
               </p>
                  <note>
                     <p>This means that when the 
                  <termref def="dt-default-namespace-elements-and-types"/>
               has the special value <code nobreak="false">##any</code>, an unprefixed name
               <var>N</var> is interpreted as a wildcard <code nobreak="false">*:<var>N</var>
                        </code>.</p>
                     <p>It is always possible to match no-namespace names explicitly
               by using the form <code nobreak="false">Q{}<var>N</var>
                        </code>
                     </p>
                  </note>
                  <p diff="chg" at="Issue23">An unprefixed <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt> is expanded using the
                  <termref def="dt-default-type-namespace-rule"/>.
                  The <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt> must be present in the <termref def="dt-is-types">in-scope schema types</termref>
                     <errorref class="ST" code="0008"/>
                  </p>
                  <note>
                     <p>If the <termref def="dt-default-namespace-elements-and-types"/>
                  has the special value <code nobreak="false">##any</code>, then an unprefixed type name
                  <var>T</var> is interpreted as <code nobreak="false">Q{http://www.w3.org/2001/XMLSchema}<var>T</var>
                        </code>.</p>
                  </note>
                  <note>
                     <p>
                        <termref def="dt-substitution-group">Substitution groups</termref> do not affect the semantics of <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>.</p>
                  </note>
                  <p diff="chg" at="Issue23">An <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>
                     <var>ET</var> matches an item <var>E</var> if the following conditions
                  are satisfied:</p>
                  <olist>
                     <item>
                        <p>
                           <var>E</var> is an element node.</p>
                     </item>
                     <item>
                        <p>If <var>ET</var> includes a <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$spec = xquery40--></nt>,
                           then the name of the element node <var>E</var> matches one or more of
                           the <nt def="prod-xquery40-NameTest">NameTests<!--$spec = xquery40--></nt> in the <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$spec = xquery40--></nt>.
                           A name <var>N</var> matches a <nt def="prod-xquery40-NameTest">NameTest<!--$spec = xquery40--></nt>
                           <var>NT</var> if one of the following
                           conditions is true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">*</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">*:<emph>local</emph>
                                 </code> and the local part
                                 of <var>N</var> is <var>local</var>.</p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">
                                    <emph>prefix</emph>:*</code> and the namespace URI
                                 of <var>N</var> matches the namespace URI bound to <var>prefix</var> in the static
                                 context.</p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">
                                    <emph>BracedURILiteral</emph>*</code> and the namespace URI
                                 of <var>N</var> matches the namespace URI found in the <code nobreak="false">BracedURILiteral</code>.</p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is an <code nobreak="false">EQName</code> equal to <var>N</var>.</p>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>If <var>ET</var> includes a <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt>
                           <var>T</var>,
                           then the <termref def="dt-type-annotation"/> of the element node <var>E</var>
                           <termref def="dt-derives-from"/>
                           <var>T</var>.</p>
                     </item>
                     <item>
                        <p>If <var>E</var> has the <code nobreak="false">nilled</code> property, then <var>ET</var>
                           either includes no <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt>, 
                           or includes a <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt> followed by the symbol <code nobreak="false">?</code>.</p>
                     </item>
                  </olist>
                  <p>Here are some examples of <nt def="doc-xquery40-ElementNodeType">ElementNodeTypes<!--$spec = xquery40--></nt>:</p>
                  <olist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element()</code> and

<code role="parse-test" nobreak="false">element(*)</code>  match any
single element node, regardless of its name or
type annotation.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person)</code> matches any element 
                        node whose name is <code nobreak="false">person</code>,
                        (in the <termref def="dt-default-namespace-elements-and-types"/>),
                     whether or not the element has been schema-validated.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person, xs:untyped)</code> matches 
                        any element node whose name is <code nobreak="false">person</code>
                        (in the <termref def="dt-default-namespace-elements-and-types"/>), provided it has
                        not been schema-validated.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person, xs:anyType?)</code> matches 
                        any element node whose name is <code nobreak="false">person</code>
                        (in the <termref def="dt-default-namespace-elements-and-types"/>), whether or
                        not it has been schema-validated. This type is equivalent to
                        <code nobreak="false">element(person)</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person, xs:anyType)</code> matches 
                        any element node whose name is <code nobreak="false">person</code>
                        (in the <termref def="dt-default-namespace-elements-and-types"/>), whether or
                        not it has been schema-validated, provided it has not been found (during
                        schema validation) to be nilled. This type is <emph>not</emph> equivalent to
                        <code nobreak="false">element(person)</code>, because it excludes nilled elements.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(doctor|nurse)</code> matches any element node whose name is 
                        <code nobreak="false">doctor</code> or <code nobreak="false">nurse</code>,
                        in the <termref def="dt-default-namespace-elements-and-types"/>.</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">element(xhtml:*)</code> matches any element node whose name is in the namespace
                        bound to the prefix <code nobreak="false">xhtml</code>.</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">element(xhtml:*|svg:*|mathml:*)</code> matches any element node whose name is one of the
                        three namespaces identified, specifically the namespaces bound to the prefixes
                        <code nobreak="false">xhtml</code>, <code nobreak="false">svg</code>, and <code nobreak="false">mathml</code>.</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">element(Q{http://www.w3.org/2000/svg}*)</code> matches any element node whose name is in the SVG namespace.</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">element(*:html)</code> matches any element node whose local name is <code nobreak="false">"html"</code>,
                     in any namespace.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person, surgeon)</code> matches a
non-nilled element node whose name is <code nobreak="false">person</code> and whose
type annotation is <code nobreak="false">surgeon</code> (or is derived from <code nobreak="false">surgeon</code>). </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person, surgeon?)</code> matches a nilled or non-nilled element node whose name is <code nobreak="false">person</code> and whose type
annotation is <code nobreak="false">surgeon</code> (or is derived from <code nobreak="false">surgeon</code>).</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(*, surgeon)</code>
matches any non-nilled element node whose type annotation is
<code nobreak="false">surgeon</code> (or is derived from <code nobreak="false">surgeon</code>), regardless of its name.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(*, surgeon?)</code>
matches any nilled or non-nilled element node whose type annotation is
<code nobreak="false">surgeon</code> (or is derived from <code nobreak="false">surgeon</code>), regardless of its name.</p>
                     </item>
                  </olist>
                  <p diff="add" at="Issue451">
                  Where a <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt>
                     <var>T</var> (other than 
                  <code nobreak="false">xs:anyType</code> or <code nobreak="false">xs:untyped</code>) is included in an 
                  <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>
                     <var>T</var>, an element node will only
                  match the test if it has been validated against a schema that 
                  defines type <var>T</var>; furthermore, <var>T</var> must be
                  present in the <termref def="dt-issd"/> of the static context of the
                  <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>. Although it is guaranteed that
                  type <var>T</var> will have 
                  <xtermref spec="DM40" ref="dt-schema-compatible">compatible</xtermref>
                  definitions in the schema that was used for validation and in the
                  <termref def="dt-issd"/>, it is not guaranteed that revalidation
                  using the <termref def="dt-issd"/> would succeed. For example, if
                  substitution group membership varies between the two schemas, the element
                  node may contain children or descendants that the <termref def="dt-issd"/>
                  would not allow.
               </p>
                  <note>
                     <p>Technically, <code nobreak="false">element(p|q)</code> is not the same type as
               the choice item type <code nobreak="false">(element(p)|element(q))</code>. However, (a)
               they match exactly the same set of element nodes, and (b) each is a subtype
               of the other, so in practice they are indistinguishable.</p>
                  </note>
                  <div5 id="id-schema-element-test">
                     <head>Schema Element Types</head>
                     <scrap headstyle="show">
                        <prod id="doc-xquery40-SchemaElementNodeType">
                           <lhs>SchemaElementNodeType</lhs>
                           <rhs>"schema-element"  "("  <nt def="prod-xquery40-ElementName">ElementName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                        </prod>

                        <prod id="doc-xquery40-SchemaElementNodeType-ElementName">
                           <lhs>ElementName</lhs>
                           <rhs>
                              <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                           </rhs>
                        </prod>

                        <prod id="doc-xquery40-SchemaElementNodeType-EQName">
                           <lhs>EQName</lhs>
                           <rhs>
                              <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                           </rhs>
                        </prod>
                     </scrap>
                     <p>
    A <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt> matches an element node against a corresponding
    element declaration found in the <termref def="dt-is-elems">in-scope element declarations</termref>.
  </p>
                     <p>
    The <nt def="prod-xquery40-ElementName">ElementName<!--$spec = xquery40--></nt> of a <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt>
    has its prefixes expanded to a namespace URI by means of the
    <termref def="dt-static-namespaces">statically known namespaces</termref>, or if unprefixed, the
                  is interpreted according to the
                  <termref def="dt-default-namespace-elements-and-types"/>. If this has the special
                  value <code nobreak="false">"##any"</code>, an unprefixed name represents a name in no namespace.

    If the <nt def="prod-xquery40-ElementName">ElementName<!--$spec = xquery40--></nt> specified in the <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt>
    is not found in the <termref def="dt-is-elems">in-scope element declarations</termref>, a
    <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0008"/>.
  </p>
                     <p>
    A <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt> matches a candidate element node if all of the following conditions are satisfied:
  </p>
                     <olist>
                        <item>
                           <p>Either:</p>
                           <olist>
                              <item>
                                 <p>The name <var>N</var> of the candidate node matches the specified <nt def="prod-xquery40-ElementName">ElementName<!--$spec = xquery40--></nt>, or</p>
                              </item>
                              <item>
                                 <p>The name <var>N</var> of the candidate node matches the name of an element declaration 
                              that is a member of the actual substitution group headed by the declaration of element <nt def="prod-xquery40-ElementName">ElementName<!--$spec = xquery40--></nt>.</p>
                              </item>
                           </olist>
                           <note>
                              <p>The term “actual substitution group” is defined in <bibref ref="XMLSchema11"/>. The actual substitution group of an element declaration 
                           <var>H</var> includes those element declarations 
                           <var>P</var> that are declared to have <var>H</var> as their 
                           direct or indirect substitution group head, provided that 
                           <var>P</var> is not declared as abstract, and that <var>P</var> 
                           is validly substitutable for <var>H</var>, which means that 
                           there must be no blocking constraints that prevent substitution.</p>
                           </note>
                        </item>
                        <item>
                           <p>The schema element declaration named <var>N</var> is not abstract.</p>
                        </item>
                        <item>
                           <p>
                              <var>AT</var>
                              <termref def="dt-derives-from"/>
                              <var>ET</var>,
                        where <var>AT</var> is the type annotation of the candidate node 
                        and <var>ET</var> is the schema type referenced by the <code nobreak="false">{type definition}</code> 
                        property of the global schema element declaration named <var>N</var>.</p>
                           <note>
                              <p>If the element declaration has no explicit <code nobreak="false">type</code> attribute
                        or <code nobreak="false">xs:simpleType</code> or <code nobreak="false">xs:complexType</code> child, but
                        is a member of a substitution group, then the <code nobreak="false">{type definition}</code> 
                        property defaults to the <code nobreak="false">{type definition}</code> of the first
                        element named in the <code nobreak="false">substitutionGroup</code> attribute.</p>
                           </note>
                        </item>
                        <item>
                           <p>If the schema element declaration named <var>N</var> 
                        is not nillable, then the <code nobreak="false">nilled</code> property of the candidate node 
                        is <code nobreak="false">false</code>.</p>
                        </item>
                     </olist>
                     <note>
                        <p>The broad intent of the <code nobreak="false">schema-element(<var>N</var>)</code> 
                  type is to select nodes that have been
                  validated (using strict or lax validation) against the global element declaration 
                  named <var>N</var>. An element that has been validated in this way will always match
                  the <code nobreak="false">schema-element</code> test. However, it is possible for an element node
                  to match the <code nobreak="false">schema-element(<var>N</var>)</code> test and yet be invalid against the element
                  declaration <var>N</var>. This can happen, for example, when 
                  (a) the element node has been validated against an
                  unrelated (local) element declaration having the same name and the same type, 
                  and (b) the global element
                  declaration imposes constraints beyond those implied by its 
                  <code nobreak="false">{type definition}</code> property. For example, the global element declaration
                  might define uniqueness constraints that are not present in the local element declaration
                  that was used for validation.</p>
                     </note>
                     <p>Example: The <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt>
                        <code role="parse-test" nobreak="false">schema-element(customer)</code> matches a candidate element node 
                  in the following two situations (among others):
<olist>
                           <item>
                              <p>
                                 <code nobreak="false">customer</code> is a top-level element declaration in the in-scope element declarations; 
                           the name of the candidate node is <code nobreak="false">customer</code>; the element declaration of <code nobreak="false">customer</code> 
                           is not abstract; the type annotation of the candidate node is the same as or 
                           derived from the schema type declared in the <code nobreak="false">customer</code> element declaration; 
                           and either the candidate node is not nilled, or <code nobreak="false">customer</code> is declared to be nillable.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">customer</code> is a top-level element declaration in the in-scope element declarations; 
                           the name of the candidate node is <code nobreak="false">client</code>; <code nobreak="false">client</code> is an actual 
                           (non-abstract and non-blocked) member of the substitution group of 
                           <code nobreak="false">customer</code>; the type annotation of the candidate node is the same as or 
                           derived from the schema type declared for the <code nobreak="false">client</code> element; 
                           and either the candidate node is not nilled, or <code nobreak="false">client</code> is 
                           declared to be nillable.</p>
                           </item>
                        </olist>
                     </p>
                     <p diff="add" at="Issue451">
                  In the case where the schema <var>X</var> used to validate an element node 
                  <var>E</var> (whose name is <var>N</var>)
                  differs from the schema <var>Y</var> represented by the
                  <termref def="dt-issd"/> in the static context of the 
                  <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt>, the following
                  considerations apply:</p>
                     <ulist>
                        <item>
                           <p>In applying the test <code nobreak="false">
                                 <var>AT</var> derives-from <var>ET</var>
                              </code>,
                  note that <var>AT</var> will necessarily be present in <var>X</var>,
                  but not necessarily in <var>Y</var>. However, <var>ET</var> will 
                  necessarily be present in both; and because the two schemas
                  must be <xtermref spec="DM40" ref="dt-schema-compatible">compatible</xtermref>,
                  <var>ET</var> will be the present in both schemas, will have the same
                  definition in both, and will be the declared type of <var>N</var> in both.
                  The test can therefore be applied from knowledge of type <var>AT</var>
                  as defined in schema <var>X</var>.</p>
                        </item>
                        <item>
                           <p>The test as to whether the element name <var>N</var> is a member
                  of the actual substitution group is performed entirely by reference
                  to schema <var>Y</var>. Although the two schemas are compatible,
                  substitution group membership can vary.</p>
                        </item>
                     </ulist>
                  </div5>
               </div4>
               <div4 id="id-attribute-test">
                  <head>Attribute Types</head>
                  <changes>
                     <change issue="107" PR="286" date="2023-01-17">
                     Element and attribute tests of the form <code nobreak="false">element(N)</code>
                     and <code nobreak="false">attribute(N)</code> now allow <code nobreak="false">N</code> to be any <code nobreak="false">NameTest</code>,
                     including a wildcard.
                  </change>
                     <change issue="23" PR="606" date="2023-01-17">
                     Element and attribute tests of the form <code nobreak="false">element(A|B)</code>
                     and <code nobreak="false">attribute(A|B)</code> are now allowed.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-AttributeNodeType">
                        <lhs>AttributeNodeType</lhs>
                        <rhs>"attribute"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-AttributeNodeType-NameTestUnion">
                        <lhs>NameTestUnion</lhs>
                        <rhs>(<nt def="prod-xquery40-NameTest">NameTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")</rhs>
                     </prod>

                     <prod id="doc-xquery40-AttributeNodeType-NameTest">
                        <lhs>NameTest</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-AttributeNodeType-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-AttributeNodeType-Wildcard">
                        <lhs>Wildcard</lhs>
                        <rhs>"*"<br/>|  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":*")<br/>|  ("*:"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>)<br/>|  (<nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  "*")</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-AttributeNodeType-TypeName">
                        <lhs>TypeName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>
                  </scrap>
                  <p>
    An <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt> is used to match an
    attribute node by its name and/or <termref def="dt-type-annotation">type annotation</termref>.
  </p>
                  <p>An unprefixed <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt>
               within the <code nobreak="false">NameTestUnion</code> is expanded using the
                  <termref def="dt-no-namespace-rule"/>.
                  The name need not be present in the <termref def="dt-is-attrs">in-scope attribute declarations</termref>.</p>
                  <p>An unprefixed <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt> is expanded using the <termref def="dt-default-type-namespace-rule"/>.
                  The <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt> must be present in the <termref def="dt-is-types">in-scope schema types</termref>
                     <errorref class="ST" code="0008"/>
                  </p>
                  <p diff="chg" at="Issue23">An <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt>
                     <var>AT</var> matches an item <var>A</var> if the following conditions
                     are satisfied:</p>
                  <olist>
                     <item>
                        <p>
                           <var>A</var> is an attribute node.</p>
                     </item>
                     <item>
                        <p>If <var>AT</var> includes a <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$spec = xquery40--></nt>,
                        then the name of the attribute node <var>A</var> matches one or more of
                        the <nt def="prod-xquery40-NameTest">NameTests<!--$spec = xquery40--></nt> in the <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$spec = xquery40--></nt>.
                        A name <var>N</var> matches a <nt def="prod-xquery40-NameTest">NameTest<!--$spec = xquery40--></nt>
                           <var>NT</var> if one of the following
                        conditions is true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">*</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">*:<emph>local</emph>
                                 </code> and the local part
                           of <var>N</var> matches <var>local</var>.</p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">
                                    <emph>prefix</emph>:*</code> and the namespace URI
                           of <var>N</var> matches the namespace URI bound to <var>prefix</var> in the static
                           context.</p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is <code nobreak="false">
                                    <emph>BracedURILiteral</emph>*</code> and the namespace URI
                              of <var>N</var> matches the namespace URI found in the <code nobreak="false">BracedURILiteral</code>.</p>
                           </item>
                           <item>
                              <p>
                                 <var>NT</var> is an <code nobreak="false">EQName</code> equal to <var>N</var>.</p>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>If <var>AT</var> includes a <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt>
                           <var>T</var>,
                        then the <termref def="dt-type-annotation"/> of the attribute node <var>A</var>
                           <termref def="dt-derives-from"/>
                           <var>T</var>.</p>
                     </item>
                  </olist>
                  <p>Here are some examples of <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt>s:
  </p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">attribute()</code> and <code role="parse-test" nobreak="false">attribute(*)</code> match any single attribute node,
regardless of its name or type annotation.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">attribute(price)</code>
                        matches any attribute node whose name is <code nobreak="false">price</code>
                        (in no namespace), regardless of its type annotation.</p>
                     </item>
                     <item diff="add" at="Issue23">
                        <p>
                           <code role="parse-test" nobreak="false">attribute(price|discount)</code>
                        matches any attribute node whose name is <code nobreak="false">price</code> or <code nobreak="false">discount</code>
                        (in no namespace).</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">attribute(xlink:*)</code> matches any attribute node whose name is in the namespace
                        bound to the prefix <code nobreak="false">xlink</code>.</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">element(Q{http://www.w3.org/2000/svg}*)</code> matches any attribute node whose name is in the SVG namespace.</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code nobreak="false">attribute(*:default-collation)</code> matches any attribute node
                        whose local name is <code nobreak="false">default-collation</code>,
                        regardless of namespace, and regardless of type annotation.</p>
                     </item>
                     <item diff="add" at="Issue23">
                        <p>
                           <code nobreak="false">attribute(*:price|*:discount)</code> matches any attribute node
                        whose local name is <code nobreak="false">price</code> or <code nobreak="false">discount</code>,
                        regardless of namespace, and regardless of type annotation.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">attribute(price, currency)</code> matches an
attribute node whose name is <code nobreak="false">price</code> (in no namespace) and whose type
annotation is
<code nobreak="false">currency</code> (or is derived from <code nobreak="false">currency</code>).</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">attribute(xlink:*, xs:string)</code> matches any attribute node whose name is in the namespace
                        bound to the prefix <code nobreak="false">xlink</code>, and whose type annotation is <code nobreak="false">xs:string</code>
                     or a type derived from <code nobreak="false">xs:string</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">attribute(*, currency)</code> matches any attribute node whose
type annotation is <code nobreak="false">currency</code> (or is derived from <code nobreak="false">currency</code>), regardless of its
name.</p>
                     </item>
                  </ulist>
                  <p diff="add" at="Issue451">
                  Unlike the situation with an <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>,
                  few problems arise if the attribute was validated using a different
                  schema. This is because simple types can never be derived by extension,
                  and attributes do not have substitution groups.</p>
                  <note>
                     <p>Technically, <code nobreak="false">attribute(p|q)</code> is not the same type as
               the choice item type <code nobreak="false">(attribute(p)|attribute(q))</code>. However, (a)
               they match exactly the same set of attribute nodes, and (b) each is a subtype
               of the other, so in practice they are indistinguishable.</p>
                  </note>
                  <div5 id="id-schema-attribute-test">
                     <head>Schema Attribute Types</head>
                     <scrap headstyle="show">
                        <prod id="doc-xquery40-SchemaAttributeNodeType">
                           <lhs>SchemaAttributeNodeType</lhs>
                           <rhs>"schema-attribute"  "("  <nt def="prod-xquery40-AttributeName">AttributeName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                        </prod>

                        <prod id="doc-xquery40-SchemaAttributeNodeType-AttributeName">
                           <lhs>AttributeName</lhs>
                           <rhs>
                              <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                           </rhs>
                        </prod>

                        <prod id="doc-xquery40-SchemaAttributeNodeType-EQName">
                           <lhs>EQName</lhs>
                           <rhs>
                              <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                           </rhs>
                        </prod>
                     </scrap>
                     <p>
    A <nt def="doc-xquery40-SchemaAttributeNodeType"><!--$spec = xquery40--></nt> matches an attribute node against a corresponding
    attribute declaration found in the <termref def="dt-is-attrs">in-scope attribute declarations</termref>.
  </p>
                     <p>
    The <nt def="prod-xquery40-AttributeName">AttributeName<!--$spec = xquery40--></nt> of a <nt def="doc-xquery40-SchemaAttributeNodeType"><!--$spec = xquery40--></nt>
    has its prefixes expanded to a namespace URI by means of the
    <termref def="dt-static-namespaces">statically known namespaces</termref>. If unprefixed, an
    <nt def="prod-xquery40-AttributeName">AttributeName<!--$spec = xquery40--></nt> is in no namespace.

    If the <nt def="prod-xquery40-AttributeName">AttributeName<!--$spec = xquery40--></nt> specified in the <nt def="doc-xquery40-SchemaAttributeNodeType"><!--$spec = xquery40--></nt>
    is not found in the <termref def="dt-is-attrs">in-scope attribute declarations</termref>, a
    <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0008"/>.
  </p>
                     <p>
    A <nt def="doc-xquery40-SchemaAttributeNodeType"><!--$spec = xquery40--></nt> matches a candidate attribute node if both of the
  following conditions are satisfied:
  </p>
                     <olist>
                        <item>
                           <p>The name of the candidate node matches the specified <nt def="prod-xquery40-AttributeName">AttributeName<!--$spec = xquery40--></nt>.</p>
                        </item>
                        <item>
                           <p>
                              <var>AT</var>
                              <termref def="dt-derives-from"/>
                              <var>ET</var>,
                        where <var>AT</var> is the type annotation of the candidate node and 
                        <var>ET</var> is the schema type (always a simple type) referenced
                        by the <code nobreak="false">{type definition}</code> property of the attribute
                        declaration for attribute <nt def="prod-xquery40-AttributeName">AttributeName<!--$spec = xquery40--></nt> in the <termref def="dt-is-attrs">in-scope attribute declarations</termref>.</p>
                        </item>
                     </olist>
                     <p>Example: The <nt def="doc-xquery40-SchemaAttributeNodeType"><!--$spec = xquery40--></nt>
                        <code role="parse-test" nobreak="false">schema-attribute(color)</code> matches a candidate attribute node if <code nobreak="false">color</code> is a top-level attribute declaration in the <termref def="dt-is-attrs">in-scope attribute declarations</termref>, the name of the candidate node is <code nobreak="false">color</code>, and the type annotation of the candidate node  is the same as or derived from the schema type declared for the <code nobreak="false">color</code> attribute.</p>
                     <p diff="add" at="Issue451">
                  Unlike the situation with a <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt>,
                  few problems arise if the attribute was validated using a different
                  schema. This is because attributes do not have substitution groups.</p>
                  </div5>
               </div4>
            </div3>
            <div3 id="id-function-map-array-tests">
               <head>Function, Map, and Array Types</head>
               <p>The following sections describe the syntax for <termref def="dt-item-type">item types</termref>
            for functions, including arrays and maps.</p>
               <p>The <termref def="dt-subtype"/> relation among these types is described in the various subsections
            of <specref ref="id-itemtype-subtype"/>.</p>
               <div4 id="id-function-test">
                  <head>Function Types</head>
                  <changes>
                     <change issue="1192" PR="1197" date="2024-05-21">The keyword <code nobreak="false">fn</code> is allowed as a synonym for <code nobreak="false">function</code>
                  in function types, to align with changes to inline function declarations.</change>
                     <change>The terms <term>FunctionType</term>, <term>ArrayType</term>,
                     <term>MapType</term>, and <term>RecordType</term> replace 
                     <term>FunctionTest</term>, <term>ArrayTest</term>,
                     <term>MapTest</term>, and <term>RecordTest</term>, with no
                  change in meaning.</change>
                     <change issue="1136" PR="1696" date="2025-01-12">
                     Parameter names may be included in a function signature; they are purely
                     documentary.
                  </change>
                  </changes>
                  <p>A <nt def="doc-xquery40-FunctionType">FunctionType<!--$spec = xquery40--></nt> matches selected <termref def="dt-function-item">function items</termref>,
                  potentially checking their <xtermref spec="DM40" ref="dt-signature">signature</xtermref>
                  (which includes the types of the arguments and results).</p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-FunctionType">
                        <lhs>FunctionType</lhs>
                        <rhs>
                           <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  (<nt def="prod-xquery40-AnyFunctionType">AnyFunctionType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionType-Annotation">
                        <lhs>Annotation</lhs>
                        <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionType-AnyFunctionType">
                        <lhs>AnyFunctionType</lhs>
                        <rhs>("function"  |  "fn")  "("  "*"  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionType-TypedFunctionType">
                        <lhs>TypedFunctionType</lhs>
                        <rhs>("function"  |  "fn")  "("  (<nt def="prod-xquery40-TypedFunctionParam">TypedFunctionParam<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"  "as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionType-TypedFunctionParam">
                        <lhs>TypedFunctionParam</lhs>
                        <rhs>("$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "as")?  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionType-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionType-SequenceType">
                        <lhs>SequenceType</lhs>
                        <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                     </prod>
                  </scrap>
                  <p>The keywords <code nobreak="false">function</code> and <code nobreak="false">fn</code> are synonyms.</p>
                  <p role="xquery">If the <nt def="doc-xquery40-FunctionType"><!--$spec = xquery40--></nt> contains an 
               <nt def="doc-xquery40-Annotation"><!--$spec = xquery40--></nt>, then this is interpreted as a
               <termref def="dt-function-assertion"/>, as described below.</p>
                  <p>An <nt def="prod-xquery40-AnyFunctionType">AnyFunctionType<!--$spec = xquery40--></nt>
    matches any <termref def="dt-function-item"/>, including a map or an array. For example,
    the following expressions all return true:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">fn:name#1 instance of function(*)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">fn { @id } instance of function(*)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">fn:random-number-generator() instance of function(*)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ 1, 2, 3 ] instance of fn(*)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">{} instance of fn(*)</code>
                        </p>
                     </item>
                  </ulist>
                  <p>A <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$spec = xquery40--></nt> matches
    a <termref def="dt-function-item"/> if the function’s type signature (as defined in
    <xspecref spec="DM40" ref="function-items"/>) is a <termref def="dt-subtype">subtype</termref> of the <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$spec = xquery40--></nt>.</p>
                  <note>
                     <p>The keywords <code nobreak="false">function</code> and <code nobreak="false">fn</code> are synonymous.</p>
                  </note>
                  <p>If parameter names are included in a <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$spec = xquery40--></nt>,
               they are purely documentary and have no semantic effect. In particular, they
               play no part in deciding whether a particular function item matches the
               function type, and they never appear as keywords in function calls. 
               For example the construct
               <code nobreak="false">function($x as node()) as xs:string</code> designates exactly the same type
               as <code nobreak="false">function(node()) as xs:string</code>.</p>
                  <p>Any parameter names that are supplied must be distinct 
                  <errorref spec="XQ" class="ST" code="0039"/>.</p>
                  <p diff="add" at="issue730">A <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$spec = xquery40--></nt>
               may also match certain maps and arrays, as described in <specref ref="id-map-test"/> and
               <specref ref="id-array-test"/>
                  </p>
                  <p>
    Here are some examples of expressions that 
    use a <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$spec = xquery40--></nt>:
  </p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">fn:count#1 instance of function(item()*) as xs:integer</code> returns true,
                        because the signature of the function item <code nobreak="false">fn:count#1</code>
                        is <code nobreak="false">function(item()*) as xs:integer</code>.
                     </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">fn:count#1 instance of function(xs:string*) as item()</code> returns true,
                        because the signature of the function item <code nobreak="false">fn:count#1</code>
                        is a subtype of <code nobreak="false">function(xs:string*) as item()</code>.
                     </p>
                        <note>
                           <p>The same type might also be written 
                        <code nobreak="false">fn($x as xs:int, $y as xs:int) as xs:int</code>.</p>
                        </note>
                     </item>
                     <item role="xquery">
                        <p>
                           <code nobreak="false">$F instance of %my:assertion function(*)</code> is true if
                        <code nobreak="false">$F</code> is a <termref def="dt-function-item">function</termref> that satisfies the implementation-defined 
                        function assertion <code nobreak="false">%my:assertion</code>.
    </p>
                     </item>
                     <item role="xquery">
                        <p>
                           <code nobreak="false">$F instance of %my:assertion function(xs:int, xs:int) as xs:int</code> 
                        is true if <code nobreak="false">$F</code> is a <termref def="dt-function-item"/> with the function signature <code nobreak="false">function(xs:int, xs:int) as xs:int</code> 
                        that satisfies the implementation-defined function assertion <code nobreak="false">%my:assertion</code>.
    </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">function(xs:anyAtomicType) as item()*</code> matches any map, 
                        or any other function item with the required signature.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">function(xs:integer) as item()*</code> matches any array, 
                        or any other function item with the required signature.</p>
                     </item>
                  </ulist>
                  <p id="id-function-assertion" role="xquery">
                     <termdef id="dt-function-assertion" term="function assertion"> A
    <term>function assertion</term> is a predicate that restricts the
    set of functions matched by a FunctionType. It uses the same
    syntax as <specref ref="id-annotations"/>.</termdef> XQuery 4.0 does not currently
    define any function assertions, but future versions may. Other
    specifications in the XQuery family may also use function
    assertions in the future.</p>
                  <p role="xquery">If the name of a function assertion is written as a <termref def="dt-qname"/>,
                  then it is expanded using the <termref def="dt-default-annotation-namespace-rule"/>.</p>
                  <note role="xquery">
                     <p>An unprefixed QName used 
                  within a <termref def="dt-function-assertion"/> is taken to refer to the namespace
                  <code nobreak="false">http://www.w3.org/2012/xquery</code>. Since this is a 
                  <termref def="dt-reserved-namespaces">reserved namespace</termref>,
                  and no assertions are currently defined in this namespace, this means that
                  in practice, use of an unprefixed QName is always an error.
               </p>
                  </note>
                  <p role="xquery">Implementations are free to define their own function
    assertions, whose behavior is completely implementation-defined. Implementations may also provide a way for
    users to define their own function assertions.</p>
                  <p role="xquery">An implementation may raise implementation-defined
    errors or warnings for function assertions, for example if the parameters
    are not correct for a given assertion. If the namespace URI of a function 
    assertion’s <termref def="dt-expanded-qname">expanded QName</termref> 
    is not recognized by an implementation, it is ignored, and has no
    effect on the semantics of the function type.</p>
                  <note role="xquery">
                     <p>An implementation is free to raise warnings for function
    assertions that it does not recognize.</p>
                  </note>
                  <note role="xquery">
                     <p>Although function assertions use the same syntax as
    annotations, they are not directly related to annotations. If an
    implementation defines the annotation <code nobreak="false">blue</code> and uses it in
    function declarations, there is no guarantee that it will also
    define a function assertion <code nobreak="false">blue</code>, or that a function
    assertion named <code nobreak="false">blue</code> matches a function declared with
    the annotation <code nobreak="false">blue</code>. Of course, an implementation
    that does so may be more intuitive to users.</p>
                  </note>
                  <p role="xquery">
    Implementations must not define function assertions in <termref def="dt-reserved-namespaces">reserved namespaces</termref>; it is is a <termref def="dt-static-error">static error</termref>
                     <errorref class="ST" code="0045"/> for a user to define a function assertion  in a <termref def="dt-reserved-namespaces">reserved namespace</termref>.

  
  </p>
               </div4>
               <div4 id="id-map-test">
                  <head>Map Types</head>
                  <p>A <nt def="doc-xquery40-MapType">MapType<!--$spec = xquery40--></nt> designates an item type that
               either matches any map, or that matches maps whose keys and values
               are constrained to specific types.</p>
                  <scrap headstyle="show">
                     <head/>
                     <prod id="doc-xquery40-MapType">
                        <lhs>MapType</lhs>
                        <rhs>
                           <nt def="prod-xquery40-AnyMapType">AnyMapType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypedMapType">TypedMapType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-MapType-AnyMapType">
                        <lhs>AnyMapType</lhs>
                        <rhs>"map"  "("  "*"  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-MapType-TypedMapType">
                        <lhs>TypedMapType</lhs>
                        <rhs>"map"  "("  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>  ","  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-MapType-ItemType">
                        <lhs>ItemType</lhs>
                        <rhs>
                           <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-MapType-SequenceType">
                        <lhs>SequenceType</lhs>
                        <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                     </prod>
                  </scrap>
                  <p>An <nt def="prod-xquery40-AnyMapType">AnyMapType<!--$spec = xquery40--></nt>
                     <code nobreak="false">map(*)</code> matches any map.</p>
                  <p>The <nt def="doc-xquery40-MapType">MapType<!--$spec = xquery40--></nt>
                     <code nobreak="false">map(K, V)</code> matches any map where every key
                  is an instance of <code nobreak="false">K</code> and every value is an
                  instance of <code nobreak="false">V</code>.</p>
                  <p>The <xtermref spec="DM40" ref="dt-entry-order">entry-order</xtermref>
               of a map has no effect on whether the map matches a particular
               map type.</p>
                  <p diff="add" at="A">Although the grammar for <code nobreak="false">TypedMapType</code>
               allows the key to be described using the full <code nobreak="false">ItemType</code> syntax, the item type used must be
               a <termref def="dt-generalized-atomic-type"/>
                     <errorref class="ST" code="0152"/>.</p>
                  <p>For example, given a map <code nobreak="false">$M</code> whose keys are integers and whose
  results are strings, such as <code nobreak="false">{ 0: "no", 1: "yes" }</code>,
  the following following expressions deliver the result shown:
  </p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of map(*)</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of map(xs:integer, xs:string)</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of map(xs:decimal, xs:anyAtomicType)</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of map(xs:int, xs:string)</code>  returns <code nobreak="false">false</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of map(xs:integer, xs:token))</code>  returns <code nobreak="false">false</code>
                        </p>
                     </item>
                  </ulist>
                  <p diff="add" at="issue730">A map is also a function item, and therefore matches certain
               function types. Specifically, a map that matches <code nobreak="false">map(K, V)</code> also matches a function
               type of the form <code nobreak="false">function(xs:anyAtomicType) as R</code> provided that both the following
                  conditions are satisfied:</p>
                  <ulist diff="add" at="issue730">
                     <item>
                        <p>
                           <var>V</var> is a <termref def="dt-subtype"/> of <var>R</var>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">empty-sequence()</code> is a <termref def="dt-subtype"/> of <var>R</var>
                        </p>
                     </item>
                  </ulist>
                  <note diff="add" at="issue730">
                     <p>To understand this rule, consider the use of a map <code nobreak="false">$M</code> in a function 
                  call <code nobreak="false">$M($K)</code>, which is equivalent to the function call <code nobreak="false">map:get($M, $K)</code>.

                  This function accepts any atomic item for the argument <code nobreak="false">$K</code>, and hence matches
                  a function type that requires an argument type of <code nobreak="false">xs:anyAtomicType</code>. If the

                  key <code nobreak="false">$K</code> is present in the map, the result of the function will be a value of
                  type <var>V</var>; if not, it will be the empty sequence. The map is therefore substitutable
                  for the function type provided that the function type allows both a value of type <var>V</var>
                  and the empty sequence as possible results.</p>
                     <p>The key type <var>K</var> does not enter into this rule. That is because in the function call
                     <code nobreak="false">$M($K)</code>, the sought key <code nobreak="false">$K</code> does not have to be of the same
                  type as the keys actually present in the map.</p>
                     <p>The transitivity rules for item type matching mean that if an item <var>M</var>
                     matches a type <var>T</var>, and <var>T</var> is a <termref def="dt-subtype"/> 
                     of <var>U</var>, then <var>M</var> also matches type <var>U</var>. So the fact
                  that a map from integers to strings (<code nobreak="false">map(xs:integer, xs:string)</code>)
                  matches <code nobreak="false">function(xs:anyAtomicType) as xs:string?</code>
                  means that it will also match other function types such as 
                     <code nobreak="false">function(xs:integer) as xs:string?</code> and 
                     <code nobreak="false">function(xs:decimal) as xs:anyAtomicType?</code>
                     </p>
                     <p>Furthermore, the rules for
                     <termref def="dt-function-coercion"/> mean that any map can be supplied as a value in a
                     context where it does not actually match the required function type, but
                     can be coerced to a function that does. For example a map of type 
                     <code nobreak="false">map(xs:integer, xs:string)</code> can be coerced to a function of
                     type <code nobreak="false">function(xs:integer) as xs:string</code>; in this situation a type
                     error will occur only if a call on the function actually returns the empty sequence. </p>
                  </note>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of fn(*)</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of fn(xs:anyAtomicType) as item()*</code> returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of fn(xs:integer) as item()*</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of fn(xs:int) as item()*</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$M instance of fn(xs:string) as item()*</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">not($M instance of fn(xs:integer) as xs:string)</code>  returns <code nobreak="false">true</code>
                        </p>
                     </item>
                  </ulist>
                  <note>
                     <p>The last case might seem surprising; 
                     however, <termref def="dt-function-coercion">function coercion</termref> ensures that <code nobreak="false">$M</code> can be used successfully 
  anywhere that the required type is <code nobreak="false">fn(xs:integer) as xs:string</code>.</p>
                  </note>
                  <p>Rules defining whether one map type is a <termref def="dt-subtype"/> of another
               are given in <specref ref="id-item-subtype-maps"/>.</p>
               </div4>
               <div4 id="id-record-test" diff="add" at="A">
                  <head>Record Types</head>
                  <changes>
                     <change>
                     Record types are added as a new kind of <code nobreak="false">ItemType</code>, constraining
                     the value space of maps.
                  </change>
                     <!--<change issue="52" PR="728" date="2023-10-10">
                     The syntax <code>record(*)</code> is allowed; it matches any map.
                  </change>-->
                     <change issue="1491" PR="1577" date="2024-10-17">
                     The syntax <code nobreak="false">record()</code> is allowed; the only thing it matches is the empty map.
                  </change>
                     <change issue="2365" PR="2413" date="2026-01-28">
                     Extensible map types are dropped; instead, the coercion rules cause undefined
                     map entries to be discarded.
                  </change>
                  </changes>
                  <p>A <nt def="doc-xquery40-RecordType">RecordType<!--$spec = xquery40--></nt> matches maps that meet specific criteria.</p>
                  <p>For example, the <code nobreak="false">RecordType</code>
                     <code nobreak="false">record(r as xs:double, i as xs:double)</code>
		             matches a map if the map has exactly two entries: an entry with key <code nobreak="false">"r"</code>
		                whose value is a <termref def="dt-singleton"/>
                     <code nobreak="false">xs:double</code> value, and an entry with key <code nobreak="false">"i"</code>
		                whose value is also a <termref def="dt-singleton"/>
                     <code nobreak="false">xs:double</code> value.</p>
                  <p>Record types describe a subset of the value space of maps. They do not define any new kinds of
		             values, or any additional operations. They are useful in many cases to describe more accurately the
		             type of a variable, function parameter, or function result, giving benefits both in the readability
		             of the code, and in the ability of the processor to detect and diagnose type errors and to optimize
		             execution.</p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-RecordType">
                        <lhs>RecordType</lhs>
                        <rhs>"record"  "("  (<nt def="prod-xquery40-FieldDeclaration">FieldDeclaration<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-RecordType-FieldDeclaration">
                        <lhs>FieldDeclaration</lhs>
                        <rhs>
                           <nt def="prod-xquery40-FieldName">FieldName<!--$idref_lang_part = xquery40- --></nt>  "?"?  ("as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                     </prod>

                     <prod id="doc-xquery40-RecordType-FieldName">
                        <lhs>FieldName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-RecordType-StringLiteral">
                        <lhs>StringLiteral</lhs>
                        <rhs>
                           <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-RecordType-SequenceType">
                        <lhs>SequenceType</lhs>
                        <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                     </prod>
                  </scrap>
                  <!--<p>If the list of fields ends with <code>",*"</code> then the record type is said to be
		                <term>extensible</term>. For example, the <code>RecordType</code>
                  <code>record(e as element(Employee), *)</code>
		             matches a map if it has an entry with key <code>"e"</code> whose value matches <code>element(Employee)</code>,
		             regardless what other entries the map might contain.</p>-->
                  <p>For generality, the syntax <code nobreak="false">record()</code> defines a record type that has no explicit fields. 
                  The only thing it matches is an <xtermref spec="DM40" ref="dt-empty-map"/>.</p>
                  <p>A record type can describe only maps whose keys are strings.
		             A field whose key is a string can be expressed using an (unquoted) NCName if the key conforms to
		             NCName syntax, or using a (quoted) string literal otherwise.</p>
                  <p>Although constructors for named record types produce a map in which the
                  <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref> reflects
                  the order of field definitions in the record type definition,
                  the <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>
                  of a map has no effect on whether the map matches a particular
                  record type: the entries in a map do not have to be in any particular order.</p>
                  <note>
                     <p>Lookup expressions have been extended in 4.0 so that non-NCName keys can be used without
		             parentheses: <code nobreak="false">employee?"middle name"</code>
                     </p>
                  </note>
                  <p>If the type declaration for a field is omitted, then <code nobreak="false">item()*</code> is assumed: that is,
		             the map entry may have any type.</p>
                  <p>If the field name is followed by a question mark,
		             then the value must have the specified type if it is present, but it may also be absent. For example,
		             the <code nobreak="false">RecordType</code>
                     <code nobreak="false">record(first as xs:string, middle? as xs:string, last as xs:string)</code>
		                requires the map to have string-valued entries with keys <code nobreak="false">"first"</code> and <code nobreak="false">"last"</code>;
		                it also declares that if the map has an entry with key <code nobreak="false">"middle"</code>, the value of that
		                entry must be a single <code nobreak="false">xs:string</code>. Declaring the type as 
		                <code nobreak="false">record(first as xs:string, middle? as xs:string?, last as xs:string)</code> also allows
		             the entry with key <code nobreak="false">"middle"</code> to be present but empty.</p>
                  <p>A map that contains an entry whose key corresponds to no field in the record type does not
               match the record type. However, it can be coerced to such a record type when the <termref def="dt-coercion-rules"/>
               are applied. In practice this means that when the required type of an argument is declared using a record
               type, the map that is supplied as a value for this argument may contain additional fields, which are discarded
               so they are invisible to the called function.</p>
                  <!--<note>
                  <p>Within an extensible record type, a <code>FieldDeclaration</code> that is marked optional 
                     and has no declared type does not constrain the
                     map in any way, so it serves no practical purpose, but it is permitted because it may have
                     documentary value.</p>
               </note>-->
                  <p>The names of the fields in a record type must be distinct <errorref class="ST" code="0021"/>.</p>
                  <p>If a variable <code nobreak="false">$rec</code> is known to conform to a particular
		             record type, then when a lookup expression <code nobreak="false">$rec?field</code> is used, (a) the processor
		             can report a type error if <code nobreak="false">$rec</code> cannot contain an entry with name <code nobreak="false">field</code>
                   (see <specref ref="id-implausible-lookup-expressions"/>),
		             and (b) the processor can make static type inferences about the type of value returned by 
		             <code nobreak="false">$rec?field</code>.</p>
                  <note>
                     <p>(TODO: change function signatures as suggested here!) A number of functions in the standard 
                     function library use maps as function arguments;
		                this is a useful technique where the information to be supplied across the interface is highly
		                variable. However, the type signature for such functions typically declares the argument type
		                as <code nobreak="false">map(*)</code>, which gives very little information (and places very few constraints)
		                on the values that are actually passed across. Using record types offers the possibility of
		                improving this: for example, the options argument of <function>fn:parse-json</function>, previously
		                given as <code nobreak="false">map(*)</code>, can now be expressed as <code nobreak="false">record(liberal? as xs:boolean, 
		                   duplicates? as xs:string, escape? as xs:boolean, fallback as fn(xs:string) as xs:string)</code>.
		                In principle the <code nobreak="false">xs:string</code> type used to describe the <code nobreak="false">duplicates</code>
		                   option could also be replaced by a schema-defined subtype
		                of <code nobreak="false">xs:string</code> that enumerates the permitted values (<code nobreak="false">"reject"</code>,
		                   <code nobreak="false">"use-first"</code>, <code nobreak="false">"use-last"</code>). 
		                </p>
                     <p>The use of a record type in the signature of such a function causes the 
		                   <termref def="dt-coercion-rules">coercion rules</termref>
		                to be invoked. So, for example, if the function expects an entry in the map to be an <code nobreak="false">xs:double</code>
		                value, it becomes possible to supply a map in which the corresponding entry has type <code nobreak="false">xs:integer</code>.</p>
                     <p>Greater precision in defining the types of such arguments also enables better type checking,
		                better diagnostics, better optimization, better documentation, and better syntax-directed
		                editing tools.</p>
                  </note>
                  <note>
                     <p>One of the motivations for introducing record types is to enable better pattern matching
		             in XSLT when processing JSON input. With XML input, patterns are often based
		             around XML element names. JSON has no direct equivalent of XML’s element names; matching a JSON object
		             such as <code nobreak="false">{longitude: 130.2, latitude: 53.4}</code> relies instead on recognizing the property
		             names appearing in the object. XSLT 4.0, by integrating record types into pattern matching syntax,
		             allows such an object to be matched with a pattern of the form 
		                <code nobreak="false">match="record(longitude, latitude)"</code>
                     </p>
                  </note>
                  <p>Rules defining whether one record type is a <termref def="dt-subtype"/> of another
                  are given in <specref ref="id-item-subtype-records"/>.</p>
                  <div5 id="id-recursive-record-tests" diff="add" at="issue295">
                     <head>Recursive Record Types</head>
                     <p>A named record type <var>N</var> is said to be recursive if its 
                  definition includes a direct or indirect reference to <var>N</var>. 
               </p>
                     <p>For example, the following XQuery declaration defines a linked list:</p>
                     <p>
                        <eg xml:space="preserve">declare record my:list (value as item()*, next? as my:list);</eg>
                     </p>
                     <p>The equivalent in XSLT is:</p>
                     <eg xml:space="preserve">&lt;xsl:record-type name="my:list"&gt;
   &lt;xsl:field name="value" as="item()*"/&gt;
   &lt;xsl:field name="next" as="my:list" required="no"/&gt;
&lt;/xsl:record-type&gt;</eg>
                     <p>Instances of recursive record types can be constructed and interrogated in the normal way.
               For example a list of length 3 can be constructed as:</p>
                     <p>
                        <eg xml:space="preserve">{ "value": 1, "next": { "value": 2, "next": { "value": 3 } } }</eg>
                     </p>
                     <p>and the third value in the map can be retrieved as <code nobreak="false">$list?next?next?value</code>.
               In practice, recursive data structures are usually manipulated using recursive functions.</p>
                     <p>It is possible to define a recursive record type that cannot be instantiated, because it
               has no finite instances: for example (in XQuery) <code nobreak="false">declare record X (next as X);</code>.
               Such a record declaration is <termref def="dt-implausible"/>, so the processor may
               treat it as an error <errorref class="ST" code="0023"/>, but it is not obliged to do so.</p>
                     <note>
                        <p>For an example of a practical use of recursive record types, see the
               specification of the function <function>fn:random-number-generator</function>.</p>
                     </note>
                     <p>Recursive type definitions need to be handled specially by the subtyping rules; 
                  a naïve approach of simply replacing each reference to a named item type 
               with its definition would make the assessment of the subtype relationship non-terminating.
               For details see <specref ref="id-itemtype-subtype"/>.</p>
                     <note>
                        <p>While record types may be recursive, it is not possible to construct
               instances containing cyclic references. Specifically, if an instance <var>A</var> contains a reference
               to <var>B</var> then it is not possible for <var>B</var> to contain a reference to <var>A</var>.
               This is because <var>A</var> cannot contain a reference to <var>B</var>
               unless <var>B</var> exists at the time <var>A</var> is created, and since all values
               are immutable, <var>B</var> cannot subsequently be updated to refer to <code nobreak="false">A</code>.</p>
                        <p>The simplest workaround for this is to make the references indirect, via some kind of index
               based on application-allocated unique identifiers.</p>
                        <p>The data model does not forbid cycles among instances, and indeed, there are functions
               such as <function>fn:schema-type</function> that may return cyclic instances. However, such
               cycles can only be constructed using mechanisms beyond the capabilities of XQuery 4.0.
               (The structure returned by <function>fn:schema-type</function> carefully uses functions
               to represent references from one value to another, rather than making the 
               references direct. This reduces the danger that
               operations such as serialization will be non-terminating. However, it does not remove
               the difficulty that the structure cannot be built using XQuery 4.0 alone.)</p>
                     </note>
                     <example id="e-binary-tree">
                        <head>A Binary Tree</head>
                        <p>A record used to represent a node in a binary tree might be represented (using XQuery syntax) as:</p>
                        <eg xml:space="preserve">declare record t:binary-tree 
   ( left? as t:binary-tree, 
     value as item()*, 
     right? as t:binary-tree
   )</eg>
                        <p>A recursive function to walk this tree and enumerate all the values in depth-first order might be written 
                     (again using XQuery syntax) as:</p>
                        <eg xml:space="preserve">declare function t:values($tree as t:binary-tree?) as item()* {
  $tree ! (t:values(?left), ?value, t:values(?right))   
}</eg>
                     </example>
                     <example id="e-arbitrary-tree">
                        <head>An Arbitrary Tree</head>
                        <p>A record used to represent a node in a tree where each node has an arbitrary number
                     of children might be represented (using XQuery syntax) as:</p>
                        <eg xml:space="preserve">declare record t:tree as (value, children as t:tree*);</eg>
                        <p>A function to walk this tree and enumerate all the values in order might be written 
                     as:</p>
                        <eg xml:space="preserve">declare function t:flatten($tree as t:tree) as item()* {
  $tree?value, $tree?children ! t:flatten(.))   
}</eg>
                     </example>
                     <!--<example id="e-mutually-recursive-types">
                  <head>Mutually Recursive Types</head>
                  <p>The usual textbook example of mutually-recursive types is that of a <emph>forest</emph>
                  consisting of a list of <emph>trees</emph>, where each <emph>tree</emph> is a record 
                  comprising a value and a <emph>forest</emph>.
                  As the previous example shows, this structure can be defined straightforwardly in &language; without 
                  recourse to mutual recursion.</p>
                  <p>A more realistic example where mutual recursion is needed is for the schema component model
                     used in <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/>. Simplifying greatly,
                     the data representing an element declaration in XSD may contain references to a
                     complex type, which in turn will typically contain references to further 
                     element declarations. The structure therefore involves mutual recursion.</p>
                  <p>To model such a structure it is important to make sure that the type is instantiable.
                     The schema component model can contain cycles (for example an element declaration <var>E</var>
                     might have a complex type <var>T</var>, where <var>T</var> has a content model that
                     allows instances of element <var>E</var>. Values are immutable, and either
                     <var>E</var> or <var>T</var> must be created before the other exists, so there
                     is no way that each of them can refer to the other, even if the references
                     are encapsulated in functions.</p>
                  <p>A practical solution to this problem is for the components to refer
                     to each other by name, rather than directly. It will then be necessary,
                     when following references from one component to another, to dereference
                     these names, which can be achieved using a map from names to components.
                     </p>
                  <p>A simplified version of the schema component model might be written (in part) as:</p>
                  <eg>
declare record ElementDeclaration (
   name as xs:NCName,
   targetNamespace? as xs:anyURI,
   typeDefinition as (SimpleTypeDefinition | ComplexTypeDefinition),
   nillable as xs:boolean,
   abstract as xs:boolean
);
declare record SimpleTypeDefinition (
   name? as xs:NCName,
   targetNamespace? as xs:anyURI,
   baseType? as SimpleTypeDefinition,
   variety as enum("atomic", "list", "union"),
   facets as Facet*,
);
declare record ComplexTypeDefinition (
   name? as xs:NCName,
   targetNamespace? as xs:anyURI,
   baseType? as ComplexTypeDefinition,
   derivationMethod as enum("extension", "restriction"),
   contentType as record (
      variety as enum("empty", "simple", "element-only", "mixed"),
      particle? as Particle,
      simpleTypeDefinition? as SimpleTypeDefinition
   )
);
declare record Particle (
   minOccurs as xs:nonNegativeInteger,
   maxOccurs as (xs:positiveInteger | enum("unbounded")),
   term as (ElementDeclaration | Wildcard | Group)
);</eg>

               </example>-->
                  </div5>
               </div4>
               <div4 id="id-array-test">
                  <head>Array Types</head>
                  <p>An <nt def="doc-xquery40-ArrayType">ArrayType<!--$spec = xquery40--></nt> designates an item type that
               either matches all arrays, or that matches arrays whose members
               are constrained to a specific type.</p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-ArrayType">
                        <lhs>ArrayType</lhs>
                        <rhs>
                           <nt def="prod-xquery40-AnyArrayType">AnyArrayType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypedArrayType">TypedArrayType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-ArrayType-AnyArrayType">
                        <lhs>AnyArrayType</lhs>
                        <rhs>"array"  "("  "*"  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-ArrayType-TypedArrayType">
                        <lhs>TypedArrayType</lhs>
                        <rhs>"array"  "("  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-ArrayType-SequenceType">
                        <lhs>SequenceType</lhs>
                        <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                     </prod>
                  </scrap>
                  <p>An <nt def="prod-xquery40-AnyArrayType">AnyArrayType<!--$spec = xquery40--></nt>
                     <code nobreak="false">array(*)</code> matches any array.</p>
                  <p>The <nt def="prod-xquery40-TypedArrayType">TypedArrayType<!--$spec = xquery40--></nt>
                     <code nobreak="false">array(X)</code> matches any array
  in which every array member matches the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>
                     <code nobreak="false">X</code>.</p>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">[ 1, 2 ] instance of array(*)</code> returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[] instance of array(xs:string)</code> returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ "foo" ] instance of array(xs:string)</code> returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ "foo" ] instance of array(xs:integer)</code> returns <code nobreak="false">false</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ (1, 2), (3, 4) ] instance of array(xs:integer)</code> returns <code nobreak="false">false</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ (1, 2), (3, 4) ] instance of array(xs:integer+)</code> returns <code nobreak="false">true</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ [ 1, 2 ], [ 3, 4 ] ] instance of array(array(xs:integer+))</code> returns <code nobreak="false">true</code>
                        </p>
                     </item>
                  </ulist>
                  <p>An array also matches certain other <termref def="dt-item-type">item types</termref>, 
                  including:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">item()</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">function(*)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">function(xs:integer) as item()*</code>
                        </p>
                     </item>
                  </ulist>
                  <p diff="add" at="issue730">An array that matches <code nobreak="false">array(T)</code>
                  also matches the function type <code nobreak="false">function(xs:integer) as T</code>.</p>
                  <note diff="add" at="issue730">
                     <p>To understand this rule, consider the use of an array <code nobreak="false">$A</code> in a function 
                     call <code nobreak="false">$A($I)</code>, which is equivalent to the function call <code nobreak="false">array:get($A, $I)</code>.
                     This function accepts any integer for the argument <code nobreak="false">$I</code>, and the result
                     will either be an instance of <var>T</var>, or an error.</p>
                     <p>The transitivity rules for item type matching mean that if an item <var>A</var>
                     matches a type <var>T</var>, and <var>T</var> is a <termref def="dt-subtype"/> 
                     of <var>U</var>, then <var>A</var> also matches type <var>U</var>. So the fact
                     that an array of strings (<code nobreak="false">array(xs:string)</code>)
                     matches <code nobreak="false">function(xs:integer) as xs:string</code>
                     means that it will also match other function types such as 
                     <code nobreak="false">function(xs:long) as item()*</code>.</p>
                     <p>Furthermore, the rules for
                     <termref def="dt-function-coercion"/> mean that any array can be supplied as a value in a
                        context where it does not actually match the required function type, but
                        can be coerced to a function that does. For example an array of type 
                        <code nobreak="false">array(node())</code> can be coerced to a function of
                        type <code nobreak="false">function(xs:integer) as element()</code>; in this situation a type
                        error will occur only if a call on the function actually returns a node
                        that is not an element node.</p>
                  </note>
                  <p diff="del" at="issue730">The function signature of an array
  matching <code nobreak="false">array(X)</code>, treated as a function, is
  <code nobreak="false">function(xs:integer) as X</code>.  It is thus always a subtype of
  <code nobreak="false">function(xs:integer) as item()*</code>
  regardless of the actual member types in the array.  The rules for
                  <termref def="dt-function-coercion">function coercion</termref> mean that any array can be supplied as a value in
  a context where the required type has a more specific return type,
  such as <code nobreak="false">function(xs:integer) as xs:integer</code>, even when the array does
  not match in the sense required to satisfy the <code nobreak="false">instance of</code>
  operator. In such cases, a type error will occur only if an actual
  call on the array (treated as a function) returns a value that is
  not an instance of the required return type.</p>
                  <p>Rules defining whether one array type is a <termref def="dt-subtype"/> of another
                  are given in <specref ref="id-item-subtype-arrays"/>.</p>
               </div4>
            </div3>
            <div3 id="id-jnode-types">
               <head>JNode Types</head>
               <changes>
                  <change issue="2025" PR="2031" date="2025-06-13">
                     JNodes are introduced
                  </change>
               </changes>
               <p>A <nt def="doc-xquery40-JNodeType">JNodeType<!--$spec = xquery40--></nt> matches a <termref def="dt-JNode"/>.</p>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-JNodeType">
                     <lhs>JNodeType</lhs>
                     <rhs>"jnode"  "("  (("*"  |  <nt def="prod-xquery40-JRootSelector">JRootSelector<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt>)  (","  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-JNodeType-JRootSelector">
                     <lhs>JRootSelector</lhs>
                     <rhs>"("  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-JNodeType-Constant">
                     <lhs>Constant</lhs>
                     <rhs>
                        <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("-"?  <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>)  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("true"  "("  ")")  |  ("false"  "("  ")")</rhs>
                  </prod>

                  <prod id="doc-xquery40-JNodeType-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>
               </scrap>
               <p>Specifically:</p>
               <ulist>
                  <item>
                     <p>The forms <code nobreak="false">jnode()</code> and <code nobreak="false">jnode(*)</code> are
                  equivalent, and match any JNode.</p>
                  </item>
                  <item>
                     <p>The first argument constrains the value of the <term>·jkey·</term> property:</p>
                     <ulist>
                        <item>
                           <p>If there are no arguments, the default for the first argument is <code nobreak="false">*</code>.</p>
                        </item>
                        <item>
                           <p>If the first argument is an NCName, this is equivalent to writing the NCName as a string
                     literal by adding quotation marks. For example, <code nobreak="false">jnode(Status)</code> is simply an abbreviation
                     for <code nobreak="false">jnode("Status")</code>.</p>
                        </item>
                        <item>
                           <p>If the first argument is a <nt def="doc-xquery40-Constant">Constant<!--$spec = xquery40--></nt>, then it specifies
                     a value that must match the value of the <term>·jkey·</term> property of the JNode,
                     according to the rules of the <function>fn:atomic-equal</function> function.</p>
                        </item>
                        <item>
                           <p>If the first argument is <code nobreak="false">()</code>, then the <term>·jkey·</term> property
                        must be absent: that is, the JNode must be the root of a JTree.</p>
                        </item>
                        <item>
                           <p>If the first argument is <code nobreak="false">*</code>, then the <term>·jkey·</term> property
                        may take any value, or may be absent.</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>The second argument, if present, constrains the <term>·jvalue·</term> property of the JNode:</p>
                     <ulist>
                        <item>
                           <p>If the argument is omitted then there are no constraints on the 
                        <term>·jvalue·</term> property</p>
                        </item>
                        <item>
                           <p>If the argument is a sequence type, then the value of the <term>·jvalue·</term> 
                              property of the JNode must match this sequence type.</p>
                        </item>
                     </ulist>
                  </item>
               </ulist>
               <p>For example:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">jnode(*)</code> matches any JNode.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">jnode(())</code> matches a JNode that is the root of a JTree.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">jnode((), map(*))</code> matches a JNode that is the root of a JTree 
                        and whose <term>·jvalue·</term> property is an instance of <code nobreak="false">map(*)</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">jnode("first name")</code> matches any JNode whose <term>·jkey·</term> property
                     is the string <code nobreak="false">"first name"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">jnode(surname)</code> matches any JNode whose <term>·jkey·</term> property
                     is the string <code nobreak="false">"surname"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">jnode("first name", xs:string)</code> matches any JNode whose <term>·jkey·</term> property
                     is the string <code nobreak="false">"first name"</code> and whose <term>·jvalue·</term> property is an instance of
                     <code nobreak="false">xs:string</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">jnode(*, array(xs:integer))</code> matches any JNode whose 
                        <term>·jvalue·</term> property is an array of integers.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-generalized-node-types">
               <head>Generalized Node Types</head>
               <changes>
                  <change issue="2025" PR="2031" date="2025-06-13">
                     JNodes are introduced
                  </change>
               </changes>
               <p>A <nt def="doc-xquery40-GNodeType">GNodeType<!--$spec = xquery40--></nt> matches a generalized node (<termref def="dt-GNode"/>):
                  that is, it matches any <termref def="dt-XNode"/>
                  or <xtermref spec="DM40" ref="dt-JNode"/>.</p>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-GNodeType">
                     <lhs>GNodeType</lhs>
                     <rhs>"gnode"  "("  ")"</rhs>
                  </prod>
               </scrap>
               <p>The type <code nobreak="false">gnode()</code> is equivalent to the choice type <code nobreak="false">jnode() | node()</code>.</p>
            </div3>
            <div3 id="id-xs-error">
               <head>The type <code nobreak="false">xs:error</code>
               </head>
               <p>The item type <code nobreak="false">xs:error</code> has an empty value space; 
                  it never appears as a dynamic type or as the content type of a dynamic element or attribute type. 
                  
                  
                  It was defined in XML Schema in the interests of making the type system complete and closed, 
                  and it is also available in XQuery 4.0 for similar reasons.</p>
               <note>
                  <p>Even though it cannot occur in an instance, <code nobreak="false">xs:error</code> is a valid type name in a sequence type. The
                     practical uses of <code nobreak="false">xs:error</code> as a sequence type are limited, but they do exist. For instance, an error-handling function that always raises a dynamic error 
                     never returns a value, so <code nobreak="false">xs:error</code> is a good choice for the return type of the function.</p>
                  <p>The semantics of <code nobreak="false">xs:error</code> are well defined as a consequence of the fact that <code nobreak="false">xs:error</code> is defined as a union type with
                     no member types. For example:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$x instance of xs:error</code> always returns <code nobreak="false">false</code>, regardless of the value of <code nobreak="false">$x</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$x cast as xs:error</code> fails dynamically with error <xerrorref spec="FO40" class="RG" code="0001"/>,  regardless of the value of <code nobreak="false">$x</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$x cast as xs:error?</code> raises a <termref def="dt-dynamic-error">dynamic error</termref>
                           <xerrorref spec="FO40" class="RG" code="0001"/> if <code nobreak="false">exists($x)</code> returns <code nobreak="false">true</code>, and evaluates to the empty sequence if <code nobreak="false">empty($x)</code> returns <code nobreak="false">true</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">xs:error($x)</code> has the same semantics as <code nobreak="false">$x cast as xs:error?</code> (see the previous bullet point)</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$x castable as xs:error</code> evaluates to <code nobreak="false">false</code>, regardless of the value of <code nobreak="false">$x</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$x treat as xs:error</code>  raises a <termref def="dt-type-error"/>
                           <errorref code="0050" class="DY"/>, regardless of the value of <code nobreak="false">$x</code>.</p>
                     </item>
                     <item role="xquery">
                        <p>
                           <code role="parse-test" nobreak="false">let $x as xs:error := 1 return 2</code>  raises a <termref def="dt-type-error">type error</termref>
                           <errorref code="0004" class="TY"/>, which can be raised statically or dynamically, and need not be raised if the variable <code nobreak="false">$x</code> is never evaluated by the query processor.</p>
                     </item>
                     <item role="xquery">
                        <p>
                           <code nobreak="false">declare function ns:f($arg as xs:error) {...};</code> is a valid function declaration, but it always  raises a <termref def="dt-type-error">type error</termref>
                           <errorref code="0004" class="TY"/> if the function is called.</p>
                     </item>
                  </ulist>
                  <p>All of the above examples assume that <code nobreak="false">$x</code> is actually evaluated. The rules specified in <specref ref="id-errors-and-opt"/> permit an implementation to avoid evaluating <code nobreak="false">$x</code> if the result of the query does not depend upon the value of <code nobreak="false">$x</code> and thus to avoid raising an error.</p>
               </note>
            </div3>
         </div2>
         <div2 id="id-sequencetype-subtype">
            <head>Subtype Relationships</head>
            <changes>
               <change issue="196" PR="202" date="2022-10-25">The presentation of the rules for the subtype relationship between 
                  sequence types and item types has been substantially
                  rewritten to improve clarity; no change to the semantics is intended.</change>
            </changes>
            <p diff="chg" at="B">
               <termdef term="subtype" id="dt-subtype">Given two 
               <termref def="dt-sequence-type">sequence types</termref>
               or <termref def="dt-item-type">item types</termref>, the rules in this section determine if one 
               is a <term>subtype</term> of the other. If a type <var>A</var> is a subtype of type <var>B</var>,
               it follows that every value matched by <var>A</var> is also matched by <var>B</var>.</termdef>
            </p>
            <note diff="add" at="B">
               <p>The relationship <code nobreak="false">subtype(A, A)</code> is always true:
               every type is a subtype of itself.</p>
            </note>
            <note diff="add" at="B">
               <p>The converse is not necessarily true: we cannot infer that 
               if every value matched by <var>A</var> is also matched by <var>B</var>, then 
               <var>A</var> is a subtype of type <var>B</var>. For example, <var>A</var> might be
            defined as the set of strings matching the regular expression <code nobreak="false">[A-Z]*</code>, while <var>B</var>
            is the set of strings matching the regular expression <code nobreak="false">[A-Za-z]*</code>; no subtype
            relationship holds between these types.</p>
            </note>
            <p diff="chg" at="B">The rules for deciding whether one <termref def="dt-sequence-type"/> is a subtype
               of another are given in <specref ref="id-seqtype-subtype"/>. The rules for deciding whether
               one <termref def="dt-item-type"/> is a subtype of another are given in <specref ref="id-itemtype-subtype"/>.</p>
            <note diff="add" at="B">
               <p>The subtype relationship is not acyclic. There are cases where <code nobreak="false">subtype(A, B)</code> and
               <code nobreak="false">subtype(B, A)</code> are both true. This implies that <var>A</var> and <var>B</var>
               have the same value space, but they can still be different types. For example this applies when <var>A</var>
               is a union type with member types <code nobreak="false">xs:string</code> and <code nobreak="false">xs:integer</code>, while 
               <var>B</var> is a union type with member types <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:string</code>.
               These are different types (<code nobreak="false">"23" cast as A</code> produces a string, while <code nobreak="false">"23" cast as B</code>
               produces an integer, because casting is attempted to each member type in order) but both types have the same value space.
            </p>
            </note>
            <div3 id="id-seqtype-subtype">
               <head>Subtypes of Sequence Types</head>
               <p>We use the notation <code nobreak="false">A ⊑ B</code>, or <code nobreak="false">subtype(A, B)</code> to indicate that
                  a <termref def="dt-sequence-type"/>
                  <code nobreak="false">A</code> is a <termref def="dt-subtype"/> of a sequence type <code nobreak="false">B</code>.
               This section defines the rules for deciding whether any two sequence types have this relationship.</p>
               <p>To define the rules, we divide sequence types into six categories:</p>
               <ulist>
                  <item>
                     <p>The category <code nobreak="false">empty</code> includes the sequence types <code nobreak="false">empty-sequence()</code>,
                   <code nobreak="false">xs:error*</code> and <code nobreak="false">xs:error?</code>. All these sequence types
                  match the empty sequence as their only instance.</p>
                  </item>
                  <item>
                     <p>The category <code nobreak="false">void</code> includes the sequence types <code nobreak="false">xs:error</code> and <code nobreak="false">xs:error+</code>,
                  which have no instances (not even the empty sequence).</p>
                  </item>
                  <item>
                     <p>The categories <code nobreak="false">X?</code>, <code nobreak="false">X*</code>, <code nobreak="false">X</code> and <code nobreak="false">X+</code> includes all sequence types 
                     having an item type <code nobreak="false">X</code> other than <code nobreak="false">xs:error</code>, together with an occurrence indicator of 
                     <code nobreak="false">?</code> (zero or more), <code nobreak="false">*</code> (one or more), absent (exactly one), or <code nobreak="false">+</code> (one or more)
                     respectively. We use the notation <var>X/i</var> to indicate the item type of such a sequence type.</p>
                  </item>
               </ulist>
               <p>The judgement <code nobreak="false">A ⊑ B</code> is then determined by the categories of the two sequence types, as defined
               in the table below. In many cases this depends on the relationship between the item types of <code nobreak="false">A</code>
                  and <code nobreak="false">B</code>. This is denoted using the notation <code nobreak="false">
                     <var>A/i</var> ⊆ <var>B/i</var>
                  </code>, 
                  as defined in <specref ref="id-itemtype-subtype"/>.</p>
               <table role="medium">
                  <tbody>
                     <tr>
                        <th rowspan="2" colspan="2"/>
                        <th colspan="6" rowspan="1">
                           <termref def="dt-sequence-type">Sequence type</termref>
                           <var>B</var>
                        </th>
                     </tr>
                     <tr>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">empty</code>
                        </th>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>B/i</var>?</code>
                        </th>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>B/i</var>*</code>
                        </th>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>B/i</var>
                           </code>
                        </th>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>B/i</var>+</code>
                        </th>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">void</code>
                        </th>
                     </tr>
                     <tr>
                        <th rowspan="6" colspan="1">
                           <termref def="dt-sequence-type">Sequence type</termref>
                           <var>A</var>
                        </th>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">empty</code>
                        </th>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                     </tr>
                     <tr>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var>?</code>
                        </th>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                     </tr>
                     <tr>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var>*</code>
                        </th>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                     </tr>
                     <tr>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var>
                           </code>
                        </th>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">false</td>
                     </tr>
                     <tr>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var>+</code>
                        </th>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">false</td>
                        <td rowspan="1" colspan="1">
                           <code nobreak="false">
                              <var>A/i</var> ⊆ <var>B/i</var>
                           </code>
                        </td>
                        <td rowspan="1" colspan="1">false</td>
                     </tr>
                     <tr>
                        <th rowspan="1" colspan="1">
                           <code nobreak="false">void</code>
                        </th>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">true</td>
                        <td rowspan="1" colspan="1">true</td>
                     </tr>
                  </tbody>
               </table>
               <!--   <p>
                  <code>xs:error+</code> is treated the same way as <code>xs:error</code> in the above table. 
                  <code>xs:error?</code> and <code>xs:error*</code> are treated the same way as <code>empty-sequence()</code>.</p>-->
            </div3>
            <div3 id="id-itemtype-subtype">
               <head>Subtypes of Item Types</head>
               <p>We use the notation <code nobreak="false">A ⊆ B</code>, or <code nobreak="false">itemtype-subtype(A, B)</code> to indicate that
                  an <termref def="dt-item-type"/>
                  <code nobreak="false">A</code> is a <termref def="dt-subtype"/> of an item type <code nobreak="false">B</code>.
                  This section defines the rules for deciding whether any two item types have this relationship.</p>
               <p diff="chg" at="Issue451">The rules in this section apply to 
                  <termref def="dt-item-type">item types</termref>, not to 
                  <termref def="dt-item-type-designator">item type designators</termref>.
                  For example, if the name <code nobreak="false">STR</code> has been defined in the
                  static context as a <termref def="dt-named-item-type"/> referring to the type <code nobreak="false">xs:string</code>,
                  then anything said here about the type <code nobreak="false">xs:string</code> applies equally
                  whether it is designated as <code nobreak="false">xs:string</code> or as <code nobreak="false">STR</code>,
                  or indeed as the parenthesized forms <code nobreak="false">(xs:string)</code> or
                 <code nobreak="false">(STR)</code>.</p>
               <p diff="chg" at="issue295">References to <termref def="dt-named-item-type">named item types</termref> 
                  are handled as described in <specref ref="id-itemtype-subtype-aliases"/>.</p>
               <p>The relationship <code nobreak="false">A ⊆ B</code> is true
               if and only if at least one of the conditions listed in the following subsections applies:</p>
               <div4 id="id-item-subtype-general">
                  <head>General Subtyping Rules</head>
                  <p>Given <termref def="dt-item-type">item types</termref>
                     <var>A</var> and <var>B</var>, 
                     <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> is true if any of the following apply:</p>
                  <olist>
                     <item diff="chg" at="A">
                        <p>
                           <var>A</var> is <code nobreak="false">xs:error</code>.</p>
                     </item>
                     <item>
                        <p>
                           <var>B</var> is <code nobreak="false">item()</code>.</p>
                     </item>
                     <item diff="chg" at="A">
                        <p>
                           <var>A</var> and <var>B</var> are the same <termref def="dt-item-type"/>.</p>
                     </item>
                     <item diff="chg" at="A">
                        <p>There is an <termref def="dt-item-type"/>
                           <var>X</var> such that <code nobreak="false">
                              <var>A</var> ⊆ <var>X</var>
                           </code>
                              and <code nobreak="false">
                              <var>X</var> ⊆ <var>B</var>
                           </code>. (This is referred to below as the <term>transitivity rule</term>).</p>
                     </item>
                  </olist>
                  <note>
                     <p>The first rule is technically redundant: it is implied by the second rule in <specref ref="id-item-subtype-atomic"/>.
                     The type <code nobreak="false">xs:error</code> is defined as a union type with no member types; therefore it is automatically true that
                        every member type <var>T</var> satisfies <code nobreak="false">
                           <var>T</var> ⊆ <var>B</var>
                        </code>.</p>
                  </note>
               </div4>
               <div4 id="id-item-subtype-choice">
                  <head>Subtyping of Choice Item Types</head>
                  <p>The following rules determine whether <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> is true in the
                  case where either <var>A</var> or <var>B</var> or both is a <termref def="dt-choice-item-type"/>.</p>
                  <p>Firstly, if one of the operands is <emph>not</emph> a choice item type, then:</p>
                  <ulist>
                     <item>
                        <p>If it is an abstract item type that cannot be extended with new immediate subtypes,
                           then it is treated as being equivalent to a choice of its concrete subtypes. Specifically:</p>
                        <ulist>
                           <item>
                              <p>
                                 <code nobreak="false">xs:anyAtomicType</code> is treated as a choice of the 19 XSD primitive
                           atomic types (<code nobreak="false">xs:string</code>, <code nobreak="false">xs:boolean</code>, etc), plus
                           <code nobreak="false">xs:untypedAtomic</code>;</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">node()</code> is treated as <code nobreak="false">(document-node() | element() | attribute() 
                                    | text() | comment() | processing-instruction() | namespace-node())</code>;</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">gnode()</code> is treated as <code nobreak="false">(node() | jnode())</code>, where <code nobreak="false">node()</code>
                           is then further expanded as above;</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">item()</code> is treated as <code nobreak="false">(gnode() | xs:anyAtomicType | function(*))</code>,
                           where <code nobreak="false">gnode()</code> and <code nobreak="false">xs:anyAtomicType</code> are then expanded as above.</p>
                           </item>
                        </ulist>
                     </item>
                     <item>
                        <p>Otherwise, it is treated as a choice item type with a single member type.</p>
                     </item>
                  </ulist>
                  <p>Applying these rules means that both types are now choice item types. The rule is then:</p>
                  <p>
                     <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> is true if for every member type <var>a</var> in 
                  <var>A</var>, there is a member type <var>b</var> in <var>B</var> such that <code nobreak="false">
                        <var>a</var> ⊆ <var>b</var>
                     </code>.</p>
                  <p>For example:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">(xs:int | xs:long)</code> is a subtype of <code nobreak="false">(xs:decimal | xs:date)</code>
                  because both <code nobreak="false">xs:int</code> and <code nobreak="false">xs:long</code> are subtypes of <code nobreak="false">xs:decimal</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">node()</code> is a subtype of <code nobreak="false">(element() | attribute() | text() |
                     comment() | processing-instruction() | document-node() | jnode())</code> because <code nobreak="false">node()</code>
                     is an abstract type that is expanded to a choice of the seven kinds of XNode.</p>
                     </item>
                  </ulist>
                  <note>
                     <p>Because an <termref def="dt-enumeration-type"/> is defined as a choice type
                        of singleton enumerations, these
                     rules have the consequence, for example, that <code nobreak="false">enum("A", "B")</code> is a subtype
                     of <code nobreak="false">enum("A", "B", "C")</code>.</p>
                  </note>
                  <note>
                     <p>The type <code nobreak="false">xs:int</code> is not a subtype of <code nobreak="false">(xs:negativeInteger | xs:nonNegativeInteger)</code>,
                     because it does not satisfy this rule. This is despite the fact that the value space of <code nobreak="false">xs:int</code>
                     is a subset of the value space of <code nobreak="false">(xs:negativeInteger | xs:nonNegativeInteger)</code>.</p>
                  </note>
               </div4>
               <div4 id="id-item-subtype-atomic">
                  <head>Subtyping of Atomic and Union Types</head>
                  <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> is true if any of the following apply:</p>
                  <olist>
                     <item>
                        <p>
                           <var>A</var> and <var>B</var> are <termref def="dt-generalized-atomic-type">generalized atomic types</termref>, 
                              and <var>A</var>
                           <termref def="dt-derives-from"/>
                           <var>B</var>.</p>
                        <example diff="add" at="B">
                           <head>Examples:</head>
                           <ulist>
                              <item>
                                 <p>
                                    <code nobreak="false">xs:integer ⊆ xs:decimal</code> because <code nobreak="false">xs:integer</code> is derived
                                 by restriction from <code nobreak="false">xs:decimal</code>.</p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">xs:decimal ⊆ xs:numeric</code> because <code nobreak="false">xs:numeric</code> is a pure union
                                    type that includes <code nobreak="false">xs:decimal</code> as a member type.</p>
                              </item>
                           </ulist>
                        </example>
                     </item>
                     <item>
                        <p>
                           <var>A</var> is a <termref def="dt-pure-union-type"/>, 
                              and every type <var>T</var> in the transitive membership of <var>A</var>
                              satisfies <code nobreak="false">
                              <var>T</var> ⊆ <var>B</var>
                           </code>.</p>
                        <example diff="add" at="B">
                           <head>Examples:</head>
                           <ulist>
                              <item>
                                 <p>
                                    <code nobreak="false">(xs:short | xs:long) ⊆ xs:integer</code>
                                    because <code nobreak="false">xs:short ⊆ xs:integer</code> and <code nobreak="false">xs:long ⊆ xs:integer</code>.</p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">(P | Q) ⊆ (P | Q | R)</code>
                                 because <code nobreak="false">P ⊆ (P | Q | R)</code> and <code nobreak="false">Q ⊆ (P | Q | R)</code>.</p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">enum("red", "green") ⊆ xs:string</code> because the 
                                    enumeration type <code nobreak="false">enum("red") ⊆ xs:string</code> 
                                    and <code nobreak="false">enum("green") ⊆ xs:string</code>.</p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">enum("red", "green") ⊆ enum("red", "green", "blue")</code> because 
                                    <code nobreak="false">enum("red") ⊆ enum("red", "green", "blue")</code> and 
                                    <code nobreak="false">enum("green") ⊆ enum("red", "green", "blue")</code>.</p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">enum("red", "green", "blue") ⊆ (enum("red", "green") | enum("blue"))</code> because 
                                    each of the types <code nobreak="false">enum("red")</code>, <code nobreak="false">enum("green")</code>, and <code nobreak="false">enum("blue")</code>
                                    is a subtype of one of the two members of the union type.</p>
                              </item>
                           </ulist>
                        </example>
                        <!--<note><p>This rule applies both when <code>A</code> is a schema-defined union type
                              and when it is a <termref def="dt-local-union-type"/>; in addition it
                              applies when <code>A</code> is an enumeration type with multiple enumerated values,
                              which is defined to be equivalent to a union type.
                           </p></note>-->
                     </item>
                  </olist>
               </div4>
               <div4 id="id-item-subtype-enum">
                  <head>Subtyping of Enumeration Types</head>
                  <p>If <var>A</var> is a <termref def="dt-singleton-enumeration-type"/>
                     permitting the string value <var>V</var>, then <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> 
                     is true if <var>B</var> is <code nobreak="false">xs:string</code>.</p>
                  <note>
                     <p>Because a non-singleton enumeration type is defined as a choice type,
                  <code nobreak="false">
                           <var>A</var> ⊆ <var>B</var>
                        </code> also holds if <var>A</var> is
                  <code nobreak="false">enum("red")</code> and <var>B</var> is <code nobreak="false">enum("red", "green")</code>.
                  See <specref ref="id-item-subtype-choice"/>.</p>
                  </note>
                  <note>
                     <p>The type <code nobreak="false">enum("red", "green")</code> is not a subtype
                  of <code nobreak="false">xs:NCName</code>, despite the fact that all the enumerated values
                  are valid <code nobreak="false">NCName</code>s. This is because instances of <code nobreak="false">xs:NCName</code>
                  must have a type annotation of <code nobreak="false">xs:NCName</code> or a subtype thereof,
                  whereas instances of <code nobreak="false">enum("red", "green")</code> are not subject to this
                  constraint.</p>
                  </note>
                  <note>
                     <p>A type <var>T</var> derived by restriction from <code nobreak="false">xs:string</code>,
                  for example a type with the facet <code nobreak="false">length="0"</code> (which permits
                  only the zero-length string), is not a subtype of any enumeration type,
                  even if every string in the value space of <var>T</var> is an instance of
                  the enumeration type.</p>
                  </note>
               </div4>
               <div4 id="id-item-subtype-nodes">
                  <head>Subtyping of Node Types</head>
                  <p>The following subsections describe the subtype relationships
                  among node types.</p>
                  <div5 id="id-item-subtype-nodes-general">
                     <head>Subtyping Nodes: General Rules</head>
                     <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                           <var>A</var> ⊆ <var>B</var>
                        </code> is true if any of the following apply:</p>
                     <olist>
                        <item>
                           <p>
                              <var>A</var> is an <nt def="prod-xquery40-XNodeType"><!--$spec = xquery40--></nt> and <var>B</var> is <code nobreak="false">node()</code>.</p>
                           <example>
                              <head>Example:</head>
                              <p>
                                 <code nobreak="false">comment() ⊆ node()</code>
                              </p>
                           </example>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">processing-instruction(<var>N</var>)</code> for any name <var>N</var>,
                              and <var>B</var> is <code nobreak="false">processing-instruction()</code>.</p>
                           <example>
                              <head>Example:</head>
                              <p>
                                 <code nobreak="false">processing-instruction('pi') ⊆ processing-instruction()</code>
                              </p>
                           </example>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is a <nt def="doc-xquery40-JNodeType">JNodeType<!--$spec = xquery40--></nt> and <var>B</var> is a <nt def="doc-xquery40-GNodeType">GNodeType<!--$spec = xquery40--></nt>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is a <nt def="doc-xquery40-NodeTest">NodeTest<!--$spec = xquery40--></nt> and <var>B</var> is a <nt def="doc-xquery40-GNodeType">GNodeType<!--$spec = xquery40--></nt>
                           </p>
                        </item>
                     </olist>
                  </div5>
                  <div5 id="id-item-subtype-documents">
                     <head>Subtyping Nodes: Document Nodes</head>
                     <changes>
                        <change issue="1624" PR="1898" date="2025-04-07">The rules for subtyping of document node types have been refined.</change>
                     </changes>
                     <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                           <var>A</var> ⊆ <var>B</var>
                        </code> 
                     is true if any of the following rules apply.</p>
                     <p>These rules apply after expanding <code nobreak="false">document-node(<var>N</var>)</code>, where <var>N</var>
                  is a <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$spec = xquery40--></nt>, to the equivalent 
                     <code nobreak="false">document-node(element(<var>N</var>))</code>.</p>
                     <olist>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">document-node(<var>E</var>)</code> for any <var>E</var>,
                              and <var>B</var> is <code nobreak="false">document-node()</code>.</p>
                           <example>
                              <head>Examples:</head>
                              <p>
                                 <code nobreak="false">document-node(element(chap)) ⊆ document-node()</code>
                              </p>
                              <p>
                                 <code nobreak="false">document-node(*) ⊆ document-node()</code>
                              </p>
                           </example>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">document-node(<var>A/e</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">document-node(<var>B/e</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">
                                       <var>A/e</var> ⊆ <var>B/e</var>
                                    </code>
                                 </p>
                              </item>
                           </olist>
                           <example>
                              <head>Examples:</head>
                              <p>
                                 <code nobreak="false">document-node(element(title)) ⊆ document-node(element(*))</code>.</p>
                              <p>
                                 <code nobreak="false">document-node(title) ⊆ document-node(*)</code>.</p>
                           </example>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">document-node(element(<var>A/1</var>|<var>A/2</var>|..., <var>T</var>))</code> 
                              (where <var>T</var> may be absent),
                           and for each <var>A/n</var>, <code nobreak="false">document-node(element(<var>A/n</var>, <var>T</var>)) ⊆ <var>B</var>
                              </code>.</p>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">document-node(a|b) ⊆ document-node(a) | document-node(b)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">document-node(a|b) ⊆ document-node(a|b|c)</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                     </olist>
                  </div5>
                  <div5 id="id-item-subtype-elements">
                     <head>Subtyping Nodes: Elements</head>
                     <changes>
                        <change issue="2201" PR="2202" date="2025-09-23">The type <code nobreak="false">schema-element(N)</code> is now defined
                     to be a subtype of <code nobreak="false">element()</code> and of various other element tests.</change>
                     </changes>
                     <p diff="chg" at="Issue23">
                        <termdef id="dt-wildcard-matches" term="wildcard-matches">In these rules, if <var>MU</var> and <var>NU</var> 
                     are <nt def="prod-xquery40-NameTestUnion">NameTestUnions<!--$spec = xquery40--></nt>, 
                     then <var>MU</var>
                           <term>wildcard-matches</term>
                           <var>NU</var> is true if every name that matches <var>MU</var>
                     also matches <var>NU</var>.</termdef>
                     </p>
                     <p diff="chg" at="Issue23">More specifically, this is the case if for every <nt def="prod-xquery40-NameTest">NameTest<!--$spec = xquery40--></nt>
                        <var>M</var>
                     in <var>MU</var> there is a <nt def="prod-xquery40-NameTest">NameTest<!--$spec = xquery40--></nt>
                        <var>N</var> in <var>NU</var>
                     where at least one of the following applies:</p>
                     <olist>
                        <item>
                           <p>
                              <var>M</var> and <var>N</var> are the same <code nobreak="false">NameTest</code>.</p>
                        </item>
                        <item>
                           <p>
                              <var>M</var> is an <code nobreak="false">EQName</code> and <var>N</var> is a 
                        <nt def="prod-xquery40-Wildcard">Wildcard<!--$spec = xquery40--></nt> that matches <var>M</var>.</p>
                        </item>
                        <item>
                           <p>
                              <var>N</var> is the <nt def="prod-xquery40-Wildcard">Wildcard<!--$spec = xquery40--></nt>
                              <code nobreak="false">*</code>.</p>
                        </item>
                     </olist>
                     <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                           <var>A</var> ⊆ <var>B</var>
                        </code> 
                     is true if any of the following apply.</p>
                     <olist>
                        <item>
                           <p>
                              <var>A</var> is an <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt> 
                           or <nt def="doc-xquery40-SchemaElementNodeType"><!--$spec = xquery40--></nt> and
                           <var>B</var> is either <code nobreak="false">element()</code> or <code nobreak="false">element(*)</code>
                           </p>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is either <code nobreak="false">element(<var>A/n</var>)</code> or <code nobreak="false">element(<var>A/n</var>, <var>T</var>)</code>  
                                 or <code nobreak="false">element(<var>A/n</var>, <var>T</var>?)</code> for any type <var>T</var>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is either <code nobreak="false">element(<var>B/n</var>)</code> or <code nobreak="false">element(<var>B/n</var>, xs:anyType?)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/n</var>
                                    <termref def="dt-wildcard-matches"/>
                                    <var>B/n</var>
                                 </p>
                              </item>
                           </olist>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(title) ⊆ element(*)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(title, xs:string) ⊆ element(*)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">element(title|heading, xs:string) ⊆ element(*)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">element(title, xs:string) ⊆ element(title|heading)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(title, xs:string?) ⊆ element(*)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">element(title|heading, xs:string) ⊆ element(*)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(title) ⊆ element(title, xs:anyType?)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(title, xs:integer) ⊆ element(title|heading, xs:anyType?)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(title, xs:string?) ⊆ element(title, xs:anyType?)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">element(my:title|your:title) ⊆ element(*:title)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">element(my:title|my:heading) ⊆ element(my:*)</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">element(<var>A/n</var>, <var>A/t</var>)</code>.</p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">element(<var>B/n</var>, <var>B/t</var>)</code>.</p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/n</var>
                                    <termref def="dt-wildcard-matches"/>
                                    <var>B/n</var>.</p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/t</var>
                                    <termref def="dt-derives-from"/>
                                    <var>B/t</var>.</p>
                              </item>
                           </olist>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(size, xs:integer) ⊆ element(size, xs:decimal)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">element(size, xs:integer) ⊆ element(size|größe, xs:decimal)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(size, xs:integer) ⊆ element(*, xs:decimal)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(*, xs:integer) ⊆ element(*, xs:decimal)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(my:*, xs:integer) ⊆ element(*, xs:decimal)</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is either <code nobreak="false">element(<var>A/n</var>, <var>A/t</var>)</code> or 
                                 <code nobreak="false">element(<var>A/n</var>, <var>A/t</var>?)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">element(<var>B/n</var>, <var>B/t</var>?)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/n</var>
                                    <termref def="dt-wildcard-matches"/>
                                    <var>B/n</var>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/t</var>
                                    <termref def="dt-derives-from"/>
                                    <var>B/t</var>.</p>
                              </item>
                           </olist>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(size, xs:integer) ⊆ element(size, xs:decimal?)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(size, xs:integer?) ⊆ element(*, xs:decimal?)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(*, xs:integer) ⊆ element(*, xs:decimal?)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(my:*, xs:integer?) ⊆ element(*, xs:decimal?)</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">schema-element(<var>A/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">schema-element(<var>B/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>Every element declaration that is an actual member of the substitution group of <var>A/n</var> 
                                 is also an actual member of the substitution group of <var>B/n</var>.</p>
                              </item>
                           </olist>
                           <note>
                              <p>The fact that <var>P</var> is a member of the substitution group of <var>Q</var> 
                                   does not mean that every element declaration in the substitution group of <var>P</var> 
                                   is also in the substitution group of <var>Q</var>. For example, <var>Q</var> might 
                                   block substitution of elements whose type is derived by extension, while <var>P</var> does not.</p>
                           </note>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">schema-element(<var>A/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">element(*, <var>B/t</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>the schema type identified by the <code nobreak="false">{type definition}</code> 
                                 property of the element declaration of 
                              <var>A/n</var> in the <termref def="dt-static-context"/>
                                    <termref def="dt-derives-from"/>
                                    <var>B/t</var>.</p>
                              </item>
                              <item>
                                 <p>the element declaration of 
                              <var>A/n</var> in the <termref def="dt-static-context"/> is not nillable.</p>
                              </item>
                           </olist>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">schema-element(<var>A/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">element(*, <var>B/t</var>?)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>the schema type identified by the <code nobreak="false">{type definition}</code> 
                                 property of the element declaration of 
                              <var>A/n</var> in the <termref def="dt-static-context"/>
                                    <termref def="dt-derives-from"/>
                                    <var>B/t</var>.</p>
                              </item>
                           </olist>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">element(<var>A/1</var>|<var>A/2</var>|..., <var>T</var>)</code> 
                              (where <var>T</var> may be absent),
                           and for each <var>A/n</var>, <code nobreak="false">element(<var>A/n</var>, <var>T</var>) ⊆ <var>B</var>
                              </code>.</p>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(a|b) ⊆ (element(a)|element(b)|element(c))</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">element(a|b, xs:integer) ⊆ (element(a, xs:decimal) | element(b, xs:integer))</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                     </olist>
                  </div5>
                  <div5 id="id-item-subtype-attributes">
                     <head>Subtyping Nodes: Attributes</head>
                     <changes>
                        <change issue="2201" PR="2202" date="2025-09-23">The type <code nobreak="false">schema-attribute(N)</code> is now defined
                     to be a subtype of <code nobreak="false">attribute()</code> and of various other attribute tests.</change>
                     </changes>
                     <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                           <var>A</var> ⊆ <var>B</var>
                        </code> is true if any of the following apply:</p>
                     <olist>
                        <item>
                           <p>
                              <var>A</var> is an <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt> 
                              and
                              <var>B</var> is either <code nobreak="false">attribute()</code> or <code nobreak="false">attribute(*)</code>
                           </p>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is either <code nobreak="false">attribute(<var>A/n</var>)</code> or 
                                 <code nobreak="false">attribute(<var>A/n</var>, <var>T</var>)</code> 
                                 for any type <var>T</var>.</p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is either <code nobreak="false">attribute(Bn)</code> or 
                                 <code nobreak="false">attribute(<var>B/n</var>, xs:anyAtomicType)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/n</var>
                                    <termref def="dt-wildcard-matches"/>
                                    <var>B/n</var>
                                 </p>
                              </item>
                           </olist>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(code) ⊆ attribute(*)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">attribute(code|status) ⊆ attribute(*)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(code, xs:untypedAtomic) ⊆ attribute(*)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(code|status, xs:string) ⊆ attribute(code, xs:anyAtomicType)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">attribute(my:code|your:code) ⊆ attribute(*:code)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">attribute(my:code|my:status) ⊆ attribute(my:*)</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">attribute(<var>A/n</var>, <var>A/t</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">attribute(<var>B/n</var>, <var>B/t</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/n</var>
                                    <termref def="dt-wildcard-matches"/>
                                    <var>B/n</var>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>A/t</var>
                                    <termref def="dt-derives-from"/>
                                    <var>B/t</var>.</p>
                              </item>
                           </olist>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(*, xs:ID) ⊆ attribute(*, xs:string)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(my:*, xs:ID) ⊆ attribute(*, xs:string)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">attribute(code, xs:ID) ⊆ attribute(code|status, xs:string)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(code, xs:ID) ⊆ attribute(*, xs:string)</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(code, xs:ID) ⊆ attribute(*:code, xs:ID)</code>
                                    </p>
                                 </item>
                                 <item diff="add" at="Issue23">
                                    <p>
                                       <code nobreak="false">attribute(my:code|my:status, xs:ID) ⊆ attribute(my:*, xs:string)</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">schema-attribute(<var>A/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">schema-attribute(<var>B/n</var>)</code>
                              or <code nobreak="false">attribute(<var>B/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>the <termref def="dt-expanded-qname">expanded QName</termref> of <var>A/n</var> equals the <termref def="dt-expanded-qname">expanded QName</termref> of <var>B/n</var>
                                 </p>
                              </item>
                           </olist>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">schema-attribute(<var>A/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">attribute(<var>B/n</var>, <var>B/t</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>the <termref def="dt-expanded-qname">expanded QName</termref> of <var>A/n</var> equals the <termref def="dt-expanded-qname">expanded QName</termref> of <var>B/n</var>
                                 </p>
                              </item>
                              <item>
                                 <p>the schema type (always a simple type) referenced
                                  by the <code nobreak="false">{type definition}</code> property of the attribute
                                  declaration of 
                              <var>A/n</var> in the <termref def="dt-static-context"/>
                                    <termref def="dt-derives-from"/>
                                    <var>B/t</var>.</p>
                              </item>
                           </olist>
                        </item>
                        <item>
                           <p>All the following are true:</p>
                           <olist>
                              <item>
                                 <p>
                                    <var>A</var> is <code nobreak="false">schema-attribute(<var>A/n</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>B</var> is <code nobreak="false">attribute(<var>N</var>, <var>B/t</var>)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <var>N</var> is a <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$spec = xquery40--></nt> that matches
                              <var>A/n</var> (for example, <code nobreak="false">*</code>).</p>
                              </item>
                              <item>
                                 <p>the schema type (always a simple type) referenced
                                  by the <code nobreak="false">{type definition}</code> property of the attribute
                                  declaration of 
                              <var>A/n</var> in the <termref def="dt-static-context"/>
                                    <termref def="dt-derives-from"/>
                                    <var>B/t</var>.</p>
                              </item>
                           </olist>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">attribute(<var>A/1</var>|<var>A/2</var>|..., <var>T</var>)</code> (where <var>T</var> may be absent),
                           and for each <var>A/n</var>, <code nobreak="false">attribute(<var>A/n</var>, <var>T</var>) ⊆ <var>B</var>
                              </code>.</p>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(a|b) ⊆ (attribute(a)|attribute(b)|attribute(c))</code>
                                    </p>
                                 </item>
                                 <item>
                                    <p>
                                       <code nobreak="false">attribute(a|b, xs:integer) ⊆ (attribute(a, xs:decimal) | attribute(b))</code>
                                    </p>
                                 </item>
                              </ulist>
                           </example>
                        </item>
                     </olist>
                  </div5>
                  <div5 id="id-item-subtype-jnodes">
                     <head>Subtyping JNodes</head>
                     <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                           <var>A</var> ⊆ <var>B</var>
                        </code> is true 
                     if any of the following apply:</p>
                     <olist>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode()</code> (or equivalently, <code nobreak="false">jnode(*)</code>)
                         and <var>B</var> is <code nobreak="false">gnode()</code>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode(<var>C</var>)</code> and <var>B</var> is <code nobreak="false">jnode()</code>, for any constant 
                           <var>C</var>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode(*, <var>T</var>)</code> and <var>B</var> is <code nobreak="false">jnode()</code>, for any sequence type 
                           <var>T</var>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode(*, <var>T</var>)</code>, <var>B</var> is <code nobreak="false">jnode(*, <var>U</var>)</code>, 
                           and <code nobreak="false">T ⊑ U</code>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode(C, <var>T</var>)</code>, <var>B</var> is <code nobreak="false">jnode(C, <var>U</var>)</code>, 
                           for any constant <var>C</var>, and <code nobreak="false">T ⊑ U</code>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode(C, <var>T</var>)</code>, <var>B</var> is <code nobreak="false">jnode(*, <var>U</var>)</code>, 
                           for any constant <var>C</var>, and <code nobreak="false">T ⊑ U</code>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode(())</code> and <var>B</var> is <code nobreak="false">jnode(*)</code>.</p>
                        </item>
                        <item>
                           <p>
                              <var>A</var> is <code nobreak="false">jnode((), <var>T</var>)</code>, <var>B</var> is <code nobreak="false">jnode(*, <var>U</var>)</code>,
                           and <code nobreak="false">T ⊑ U</code>.</p>
                        </item>
                     </olist>
                  </div5>
               </div4>
               <div4 id="id-item-subtype-functions">
                  <head>Subtyping Functions</head>
                  <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> is true if any of the following apply:</p>
                  <olist>
                     <item>
                        <p>All the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is a <nt def="doc-xquery40-FunctionType">FunctionType<!--$spec = xquery40--></nt>
                                 <phrase role="xquery"> with annotations <code nobreak="false">[AnnotationsA]</code>
                                 </phrase>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">
                                    <phrase role="xquery">[AnnotationsB]</phrase> function(*)</code>
                              </p>
                           </item>
                           <item role="xquery">
                              <p>
                                 <code nobreak="false">subtype-assertions(AnnotationsA, AnnotationsB)</code>, 
                              where <code nobreak="false">[AnnotationsB]</code> and <code nobreak="false">[AnnotationsA]</code> 
                              are optional lists of one or more annotations.</p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">function(xs:integer) as xs:string ⊆ function(*)</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>All the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">
                                    <phrase role="xquery">AnnotationsA </phrase>function(<var>a/1</var>, <var>a/2</var>, ... <var>a/M</var>) as <var>R/A</var>
                                 </code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">
                                    <phrase role="xquery">AnnotationsB </phrase>function(<var>b/1</var>, <var>b/2</var>, ... <var>b/N</var>) as <var>R/B</var>
                                 </code>
                              </p>
                           </item>
                           <item role="xquery">
                              <p>
                                 <code nobreak="false">[AnnotationsB]</code> and <code nobreak="false">[AnnotationsA]</code> are optional lists of one or more annotations;</p>
                           </item>
                           <item>
                              <p>
                                 <var>N</var> (the arity of <var>B</var>) equals <var>M</var> (the arity of <var>A</var>)
                                    </p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">
                                    <var>R/A</var> ⊑ <var>R/B</var>
                                 </code>
                              </p>
                           </item>
                           <item>
                              <p>For all values of <var>p</var> between 1 and <var>N</var>, <code nobreak="false">
                                    <var>b/p</var> ⊑ <var>a/p</var>
                                 </code>
                                 <phrase role="xquery">, and <code nobreak="false">subtype-assertions(AnnotationsA, AnnotationsB)</code>
                                 </phrase>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Examples:</head>
                           <ulist>
                              <item>
                                 <p>
                                    <code nobreak="false">function(xs:integer) as xs:string ⊆ function(xs:long) as xs:string</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">function(xs:integer) as xs:ID ⊆ function(xs:integer) as xs:string</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">function(xs:integer) as xs:ID ⊆ function(xs:long) as xs:string</code>
                                 </p>
                              </item>
                           </ulist>
                        </example>
                        <note>
                           <p>Function return types are covariant because this rule requires <code nobreak="false">
                                 <var>R/A</var> ⊑ <var>R/B</var>
                              </code> for return types. 
                                 Function parameter types are contravariant because this rule requires <code nobreak="false">
                                 <var>b/p</var> ⊑ <var>a/p</var>
                              </code> for parameter types.</p>
                        </note>
                     </item>
                  </olist>
               </div4>
               <div4 id="id-item-subtype-maps">
                  <head>Subtyping Maps</head>
                  <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> is true if any of the following apply:</p>
                  <olist>
                     <item>
                        <p>Both of the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">map(<var>K</var>, <var>V</var>)</code>,
                                 for any <var>K</var> and <var>V</var>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">map(*)</code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">map(xs:integer, item()*) ⊆ map(*)</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>All the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">map(<var>K/a</var>, <var>V/a</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">map(<var>K/b</var>, <var>V/b</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">
                                    <var>K/a</var> ⊆ <var>K/b</var>
                                 </code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">
                                    <var>V/a</var> ⊑ <var>V/b</var>
                                 </code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">map(xs:long, item()) ⊆ map(xs:integer, item()+)</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>Both the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">map(*)</code>
                                 (or, because of the transitivity rules, any other map type)</p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">function(*)</code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">map(xs:long, xs:string?) ⊆ function(*)</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>Both the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">map(*)</code>
                                 (or, because of the transitivity rules, any other map type)</p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is 
                                 <code nobreak="false">function(xs:anyAtomicType) as item()*</code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">map(xs:long, xs:string?) ⊆ function(xs:anyAtomicType) as item()*</code>
                           </p>
                        </example>
                     </item>
                     <item diff="chg" at="issue730">
                        <p>All the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">map(<var>K</var>, <var>V</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">function(xs:anyAtomicType) as <var>R</var>
                                 </code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>V</var> ⊆ <var>R</var>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">empty-sequence()</code> ⊆ <var>R</var>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Examples:</head>
                           <ulist>
                              <item>
                                 <p>
                                    <code nobreak="false">map(xs:int, node()) ⊆ function(xs:anyAtomicType) as node()?</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">map(xs:int, node()+) ⊆ function(xs:anyAtomicType) as node()*</code>
                                 </p>
                              </item>
                           </ulist>
                           <p>The function accepts type <code nobreak="false">xs:anyAtomicType</code> rather than <code nobreak="false">xs:int</code>,
                              because <code nobreak="false">$M("xyz")</code> is a valid call on a map (treated as a function) even
                              when all the keys in the map are integers.</p>
                           <p>The return type of the function is extended from <code nobreak="false">node()</code> or <code nobreak="false">node()+</code> to allow the empty sequence
                                 because <code nobreak="false">$M("xyz")</code> can return the empty sequence even if none of the entries
                              in the map contains the empty sequence.</p>
                        </example>
                     </item>
                  </olist>
               </div4>
               <div4 id="id-item-subtype-arrays">
                  <head>Subtyping Arrays</head>
                  <p>Given item types <var>A</var> and <var>B</var>, <code nobreak="false">
                        <var>A</var> ⊆ <var>B</var>
                     </code> is true if any of the following apply:</p>
                  <olist>
                     <item>
                        <p>Both the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">array(<var>X</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">array(*)</code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">array(xs:integer) ⊆ array(*)</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>All the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">array(<var>X</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">array(<var>Y</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">
                                    <var>X</var> ⊑ <var>Y</var>
                                 </code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">array(xs:integer) ⊆ array(xs:decimal+)</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>Both the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">array(*)</code>
                                 (or, because of the transitivity rules, any other array type)</p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">function(*)</code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">array(xs:integer) ⊆ function(*)</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>Both the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">array(*)</code>
                                 (or, because of the transitivity rules, any other array type)</p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">function(xs:integer) as item()*</code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">array(*) ⊆ function(xs:integer) as item()*</code>
                           </p>
                        </example>
                     </item>
                     <item>
                        <p>Both the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is <code nobreak="false">array(<var>X</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">function(xs:integer) as <var>X</var>
                                 </code>
                              </p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">array(xs:string) ⊆ function(xs:integer) as xs:string</code>
                           </p>
                        </example>
                     </item>
                  </olist>
               </div4>
               <div4 id="id-item-subtype-records">
                  <head>Subtyping Records</head>
                  <changes>
                     <change issue="2365" PR="2413" date="2026-01-28">
                        Extensible map types are dropped; instead, the coercion rules cause undefined
                        map entries to be discarded.
                     </change>
                  </changes>
                  <p>Given item types <var>A</var> and <var>B</var>, <var>A</var>
                     <code nobreak="false">⊆</code>
                     <var>B</var> is true if any of the following apply:</p>
                  <olist><!--<item diff="add" at="issue52">
                        <p><var>A</var> is <code>map(*)</code> and <var>B</var> is <code>record(*)</code>.</p>
                     </item>-->
                     <item diff="add" at="A">
                        <p>All of the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is a record type.</p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">map(*)</code>.</p>
                           </item>
                        </olist>
                        <example>
                           <head>Example:</head>
                           <p>
                              <code nobreak="false">record(longitude, latitude)</code> ⊆ <code nobreak="false">map(*)</code>
                           </p>
                           <p>
                              <code nobreak="false">record(longitude as xs:double, latitude as xs:double)</code> ⊆ <code nobreak="false">map(*)</code>
                           </p>
                           <p>
                              <code nobreak="false">record(longitude, latitude, altitude?)</code> ⊆ <code nobreak="false">map(*)</code>
                           </p>
                        </example>
                     </item>
                     <item diff="add" at="A">
                        <p>All of the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is a record type</p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is <code nobreak="false">map(<var>K</var>, <var>V</var>)</code>
                              </p>
                           </item>
                           <item>
                              <p>
                                 <var>K</var> is either <code nobreak="false">xs:string</code> or <code nobreak="false">xs:anyAtomicType</code>
                              </p>
                           </item>
                           <item>
                              <p>For every field <var>F</var> in <var>A</var>,
                              where <var>T</var> is the declared type of <var>F</var> (or its default, <code nobreak="false">item()*</code>),
                              <code nobreak="false">
                                    <var>T</var> ⊑ <var>V</var>
                                 </code>.</p>
                           </item>
                        </olist>
                        <example>
                           <head>Examples:</head>
                           <ulist>
                              <item>
                                 <p>
                                    <code nobreak="false">record(x, y)</code> ⊆ <code nobreak="false">map(xs:string, item()*)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">record(x as xs:double, y as xs:double)</code> ⊆ <code nobreak="false">map(xs:string, xs:double)</code>
                                 </p>
                              </item>
                           </ulist>
                        </example>
                     </item>
                     <item diff="add" at="A">
                        <p>All of the following are true:</p>
                        <olist>
                           <item>
                              <p>
                                 <var>A</var> is a record type.</p>
                           </item>
                           <item>
                              <p>
                                 <var>B</var> is a record type.</p>
                           </item>
                           <item>
                              <p>Every field in <var>A</var> is also declared in <var>B</var>.</p>
                           </item>
                           <item>
                              <p>Every mandatory field in <var>B</var> is also declared  as mandatory in <var>A</var>.</p>
                           </item>
                           <item>
                              <p>For every field that is declared in both <var>A</var> and <var>B</var>,
                              where the declared type in <var>A</var> is <var>T</var> 
                              and the declared type in <var>B</var> is <var>U</var>, <code nobreak="false">
                                    <var>T</var> ⊑ <var>U</var>
                                 </code>.</p>
                           </item>
                        </olist>
                        <example>
                           <head>Examples:</head>
                           <ulist>
                              <item>
                                 <p>
                                    <code nobreak="false">record(x, y as xs:integer) ⊆ record(x, y as xs:decimal)</code>
                                 </p>
                              </item>
                              <item>
                                 <p>
                                    <code nobreak="false">record(x, y) ⊆ record(x, y, z?)</code>
                                 </p>
                              </item>
                           </ulist>
                        </example>
                     </item>
                     <!--<item diff="add" at="A">
                           <p>All of the following are true:</p>
                           <olist>
                              <item><p><var>A</var> is an extensible record type</p></item>
                              <item><p><var>B</var> is an extensible record type</p></item>
                              <item><p>Every mandatory field in <var>B</var> is also declared  as mandatory in <var>A</var>.</p></item>
                              <item><p>For every field that is declared in both <var>A</var> and <var>B</var>,
                                 where the declared type in <var>A</var> is <var>T</var> 
                                 and the declared type in <var>B</var> is <var>U</var>, <code><var>T</var> ⊑ <var>U</var></code>.</p></item> 
                              <item><p>For every field that is declared in <var>B</var>
                                 but not in <var>A</var>, the declared type in <var>B</var> is <code>item()*</code>.</p>
                              </item>  
                           </olist>
                           <example>
                              <head>Examples:</head>
                              <ulist>
                                 <item><p><code>record(x, y, z, *) ⊆ record(x, y, *)</code></p></item>
                                 <item><p><code>record(x?, y?, z?, *) ⊆ record(x, y, *)</code></p></item>
                                 <item><p><code>record(x as xs:integer, y as xs:integer, *) ⊆ record(x as xs:decimal, y as xs:integer*, *)</code></p></item>
                                 <item><p><code>record(x as xs:integer, *) ⊆ record(x as xs:decimal, y as item(), *)</code></p></item>                               
                              </ulist>
                           </example>
                           
                        </item>-->
                     <!--<item diff="add" at="A">
                        <p>All of the following are true:</p>
                        <olist>
                           <item><p><var>A</var> is a non-extensible record type.</p></item>
                           <item><p><var>B</var> is an extensible record type.</p></item>
                           <item><p>Every mandatory field in <var>B</var> is also declared as mandatory in <var>A</var>.</p></item>
                           <!-\-<item><p>Every field that is declared in <var>B</var> with a type other than <code>item()*</code>
                              is also declared in <var>A</var>.</p></item>-\->
                           <item><p>For every field that is declared in both <var>A</var> and <var>B</var>,
                              where the declared type in <var>A</var> is <var>T</var> 
                              and the declared type in <var>B</var> is <var>U</var>, <code><var>T</var> ⊑ <var>U</var></code>.</p>                               
                           </item>
                        </olist>
                        <example>
                           <head>Examples:</head>
                           <ulist>
                              <item><p><code>record(x, y as xs:integer) ⊆ record(x, y as xs:decimal, *)</code></p></item>
                              <item><p><code>record(y as xs:integer) ⊆ record(x?, y as xs:decimal, *)</code></p></item>
                           </ulist>
                        </example>
                     </item>-->
                  </olist>
               </div4>
               <div4 id="id-itemtype-subtype-aliases" diff="add" at="issue295">
                  <head>Subtyping of Named Item Types</head>
                  <p>This section describes how references to <termref def="dt-named-item-type">named item types</termref>
                  are handled when evaluating the subtype relationship.</p>
                  <p>Named item types can be classified as recursive or non-recursive. 
                     A recursive type is one that references itself, directly or indirectly. Only named record
                  types are allowed to be recursive.</p>
                  <p>In the case of references to non-recursive named item types, the reference
                  is fully expanded as the first step in evaluating the subtype relationship. For example
                  this means that if <var>U</var> is a named item type with the expansion 
                     <code nobreak="false">(xs:integer | xs:double)</code>,
                     then <code nobreak="false">xs:integer ⊆ U</code> is true, because 
                     <code nobreak="false">xs:integer ⊆ (xs:integer | xs:double)</code> is true.</p>
                  <p>Recursive record types are considered to be, in the terminology of the computer science
                  literature, <term>iso-recursive</term> (rather than <term>equi-recursive</term>). 
                     This means that a recursive type name is not
                  treated as being equivalent to its expansion (at any depth). 
                  For example, if the named item type <var>T</var>
                  has the expansion <code nobreak="false">record(A as item()*, B as T?)</code>, then the type 
                     <code nobreak="false">array(T)</code> is not considered to be equivalent to 
                     <code nobreak="false">array(record(A as item()*, B as T?))</code>, despite the fact
                  that the two types have exactly the same instances.</p>
                  <p>The rules are therefore defined as follows:</p>
                  <ulist>
                     <item>
                        <p>If <var>B</var> is a reference to a recursive record type, then
                        <var>A</var> ⊆ <var>B</var> is true if and only if 
                        <var>A</var> and <var>B</var>
                        are references to the same named record type.</p>
                     </item>
                     <item>
                        <p>If <var>A</var> is a reference to a recursive named item type, then
                        <var>A</var> ⊆ <var>B</var> is true if and only if 
                        <var>A</var> and <var>B</var>
                        are references to the same named record type.</p>
                     </item>
                  </ulist>
                  <note>
                     <p>The decision to make recursive types iso-recursive rather than equi-recursive
                  was made largely because it saves a great deal of implementation complexity without any serious
                  adverse effects for users. In practice, problems can be avoided by using named record types
                  consistently (for example, avoiding having two named record types with
                  different names but identical definitions).</p>
                  </note>
               </div4>
            </div3>
            <div3 id="id-assertions-subtype" role="xquery">
               <head>The judgement <code nobreak="false">subtype-assertions(AnnotationsA, AnnotationsB)</code>
               </head>
               <p>
      The judgement <code nobreak="false">subtype-assertions(AnnotationsA, AnnotationsB)</code> determines if <code nobreak="false">AnnotationsA</code> is a subtype of <code nobreak="false">AnnotationsB</code>,
      where <code nobreak="false">AnnotationsA</code> and <code nobreak="false">AnnotationsB</code> are annotation lists from two FunctionTypes.
      It is defined to ignore function assertions in namespaces not understood by the XQuery
      implementation. For assertions that are understood, their effect on the result
      of <code nobreak="false">subtype-assertions()</code> is implementation defined.
    </p>
               <p>
      The following examples are some possible ways to define <code nobreak="false">subtype-assertions()</code> for some
      implementation defined assertions in the <code nobreak="false">local</code> namespace. These examples 
                  assume that some implementation uses annotations to label functions as 
                  deterministic or nondeterministic, and treats deterministic functions 
                  as a subset of nondeterministic functions. In this implementation, 
                  nondeterministic functions are not a subset of deterministic functions.
    </p>
               <ulist>
                  <item>
                     <p>
        AnnotationsA is
        <eg xml:space="preserve">%local:inline</eg>
        It has no influence on the outcome of <code nobreak="false">subtype-assertions()</code>.
      </p>
                  </item>
                  <item>
                     <p>
        AnnotationsA is
        <eg xml:space="preserve">%local:deterministic</eg>
        AnnotationsB is
        <eg xml:space="preserve">%local:nondeterministic</eg>
        Since deterministic functions are a subset of nondeterministic functions, <code nobreak="false">subtype-assertions()</code> is true.
      </p>
                  </item>
                  <item>
                     <p>
        AnnotationsA contains
        <eg xml:space="preserve">%local:nondeterministic</eg>
        AnnotationsB is empty.
        If FunctionTypes without the <code nobreak="false">%local:nondeterministic</code> annotation only match deterministic functions,
        <code nobreak="false">subtype-assertions()</code> must be false.
      </p>
                  </item>
               </ulist>
            </div3>
         </div2>
         <div2 id="id-coercion-rules">
            <head>Coercion Rules</head>
            <changes>
               <change PR="254" date="2022-11-29">
                  The term "function conversion rules" used in 3.1 has been replaced by the term "coercion rules".
               </change>
               <change issue="117" PR="254" date="2022-11-29">
                  The coercion rules allow “relabeling” of a supplied atomic item where
                  the required type is a derived atomic type: for example, it is now permitted to supply
                  the value 3 when calling a function that expects an instance of <code nobreak="false">xs:positiveInteger</code>.
               </change>
               <change issue="980" PR="911" date="2024-01-30">
                  The coercion rules now allow any numeric type to be implicitly converted to any other, for example
                  an <code nobreak="false">xs:double</code> is accepted where the required type is <code nobreak="false">xs:decimal</code>.
               </change>
               <change issue="130 480" PR="815" date="2023-11-07">
                  The coercion rules now allow conversion in either direction between <code nobreak="false">xs:hexBinary</code>
                  and <code nobreak="false">xs:base64Binary</code>.
               </change>
               <change issue="1318" PR="1501" date="2024-10-29">
                  The coercion rules now apply recursively to the members of an array and the entries in a map.
               </change>
               <change issue="1862" PR="1874" date="2025-03-25">
                  The coercion rules now reorder the entries in a map when the required type is a record type.
               </change>
            </changes>
            <p diff="chg" at="2022-11-17">
               <termdef term="coercion rules" id="dt-coercion-rules">The <term>coercion rules</term> are rules used to convert a supplied value to a required type,
                     for example when converting an argument of a function call to the declared type of the function parameter.
                  </termdef> The required type is expressed as a <termref def="dt-sequence-type">sequence type</termref>. The effect of the coercion rules may be to accept the value as supplied,
                  to convert it to a value that matches the required type, or to reject it with a type error.</p>
            <p diff="chg" at="2022-11-17">This section defines how the coercion rules operate; the situations in which the rules apply
                  are defined elsewhere, by reference to this section.</p>
            <note diff="add" at="A">
               <p>In previous versions of this specification, the coercion rules were referred to as the
                              <emph>function conversion</emph> rules. The terminology has changed because the rules are not exclusively
                              associated with functions or function calling.</p>
            </note>
            <p diff="chg" at="2023-03-11">If the required type is <code nobreak="false">empty-sequence()</code>, 
                  no coercion takes place (the supplied
               value must be the empty sequence, or a type error occurs).</p>
            <p>In all other cases, the required 
                  <termref def="dt-sequence-type"/>
               <var>T</var> comprises a required <termref def="dt-item-type"/>
               <var>R</var> 
                  and an optional occurrence indicator. The coercion rules are then 
                  applied to a supplied value <var>V</var> 
               and the required type <var>T</var> as follows:</p>
            <olist>
               <item>
                  <p>Each item in <var>V</var> is processed against the required item type <var>R</var>
                     using the item coercion rules defined
                  in <specref ref="id-item-coercion-rules"/>, and the results are sequence-concatenated
                  into a single sequence <var>V'</var>.</p>
               </item>
               <item>
                  <p>A type error is raised if the cardinality of <var>V'</var> does not match the
                  required cardinality of <var>T</var>
                     <errorref code="0004" class="TY"/>.</p>
               </item>
            </olist>
            <div3 id="id-item-coercion-rules">
               <head>Item Coercion Rules</head>
               <p>The rules in this section are used to process each item <var>J</var> in a supplied
               sequence, given a required <termref def="dt-item-type"/>
                  <var>R</var>.</p>
               <olist>
                  <item>
                     <p>If <var>R</var> is a <termref def="dt-generalized-atomic-type"/>
                     (for example, if it is an <termref def="dt-atomic-type"/>,
                     a <termref def="dt-pure-union-type"/>, or
                     an <termref def="dt-enumeration-type"/>), and <var>J</var>
                     is not an atomic item, then:
                     <olist>
                           <item>
                              <p>
                                 <var>J</var> is <termref def="dt-atomization">atomized</termref> 
                           to produce a sequence of atomic items <var>JJ</var>.</p>
                           </item>
                           <item>
                              <p>Each atomic item in <var>JJ</var> is coerced to the required
                        type <var>R</var> by recursive application of the item coercion rules (the 
                        rules in this section) to produce a value <var>V</var>.</p>
                           </item>
                           <item>
                              <p>The result is the <termref def="dt-sequence-concatenation"/> 
                           of the <var>V</var> values.</p>
                           </item>
                        </olist>
                     </p>
                     <note>
                        <p>For example, if <code nobreak="false">J</code> is an element with type annotation
                  <code nobreak="false">xs:integer</code>, and <code nobreak="false">R</code> is the union type <code nobreak="false">xs:numeric</code>,
                  then the effect is to atomize the element to an <code nobreak="false">xs:integer</code>, and then
                  to coerce the resulting <code nobreak="false">xs:integer</code> to <code nobreak="false">xs:numeric</code>
                  (which leaves the integer unchanged). This is not the same as attempting to
                  coerce the element to each of the alternatives of the union type in turn, which
                  would deliver an instance of <code nobreak="false">xs:double</code>.</p>
                     </note>
                  </item>
                  <item>
                     <p>Otherwise, if <var>R</var> is a <termref def="dt-choice-item-type"/> or
                     a <termref def="dt-pure-union-type"/> (which includes the case where
                     it is an <termref def="dt-enumeration-type"/>), then:</p>
                     <olist>
                        <item>
                           <p>If <var>J</var> matches (is an instance of) one of the alternatives
                           in <var>R</var>, then <var>J</var> is coerced to the first alternative in 
                           <var>R</var> that <var>J</var> matches.</p>
                           <note>
                              <p>There are two situations where coercing an item to a type that
                              it already matches does not simply return the item unchanged:</p>
                              <ulist>
                                 <item>
                                    <p>When the required type is a typed function type
                                      (see <specref ref="id-function-test"/>),
                                    then function coercion is applied to coerce <var>J</var> to that
                                    function type, as described in <specref ref="id-function-coercion"/>.</p>
                                 </item>
                                 <item>
                                    <p>When the required type is a record type and the supplied
                                 value is a map, then coercion may change the <xtermref spec="DM40" ref="dt-entry-order"/>
                                 of the entries in the map.</p>
                                 </item>
                              </ulist>
                           </note>
                        </item>
                        <item>
                           <p>Otherwise, the item coercion rules (the rules in this section)
                              are applied to <var>J</var> recursively
                              with <var>R</var> set to each of the alternatives in the
                              choice or union item type, in order, until an alternative is found that
                              does not result in a type error; a type error is raised
                              only if all alternatives fail.</p>
                           <p>The error code used in the event of failure 
                              should be the error code arising from the
                              first unsuccessful matching attempt. (The diagnostic information
                              associated with the error may also describe how further attempts
                              failed.)</p>
                        </item>
                     </olist>
                     <note>
                        <p>Suppose the required type is <code nobreak="false">(xs:integer | element(e))*</code>
                           and the supplied value is the sequence 
                           <code nobreak="false">(&lt;e&gt;22&lt;/e&gt;, 23, &lt;f&gt;24&lt;/f&gt;)</code>. 
                        Item coercion is applied independently to each of the three items in this
                        sequence. The first item matches one of the alternatives, namely <code nobreak="false">element(e)</code>,
                        so it is returned unchanged as an element node. The second item (the integer 23) also matches one of the
                        alternatives, and is returned unchanged as an integer. The third item does not match any of
                        the alternatives, so coercion is attempted to each one in turn. Coercion
                        to type <code nobreak="false">xs:integer</code> succeeds (by virtue of atomization and untyped
                           atomic conversion), so the final result is the sequence <code nobreak="false">(&lt;e&gt;22&lt;/e&gt;, 23, 24)</code>
                        </p>
                     </note>
                     <note>
                        <p>Suppose the required type is <code nobreak="false">enum("red", "green", "blue")</code>
                           and the supplied value is <code nobreak="false">"green"</code>. The enumeration type is defined
                           as a choice item type whose alternatives are singleton enumerations, so the rules
                           are applied first to the type <code nobreak="false">enum("red")</code> (which fails), and
                           then to the type <code nobreak="false">enum("green")</code> (which succeeds). The strings in an
                           enumeration type are required to be distinct so the order
                           of checking is in this case immaterial. The supplied value will be accepted, and
                           will be relabeled if necessary as an instance of <code nobreak="false">xs:string</code>.</p>
                     </note>
                     <note>
                        <p>Schema-defined union types behave in exactly the same way as
                        <termref def="dt-choice-item-type">choice item types.</termref>
                        </p>
                     </note>
                  </item>
                  <item>
                     <p>If <var>R</var> is an <termref def="dt-atomic-type"/>
                     and <var>J</var> is an <termref def="dt-atomic-item"/>, then:</p>
                     <olist>
                        <item diff="chg" at="2024-01-04">
                           <p>If <var>J</var> is an instance of 
                           <var>R</var> then it is used unchanged.</p>
                        </item>
                        <item>
                           <p>If <var>J</var> is an instance of type <code nobreak="false">xs:untypedAtomic</code>
                        then:</p>
                           <olist>
                              <item>
                                 <p>If <var>R</var> is <termref def="dt-namespace-sensitive">namespace-sensitive</termref> then 
                                    a <termref def="dt-type-error">type error</termref>
                                    <errorref class="TY" code="0117"/> is raised.</p>
                              </item>
                              <item>
                                 <p>Otherwise,  <var>J</var> is cast to type <var>R</var>.</p>
                              </item>
                           </olist>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>If there is an entry (<var>from</var>, <var>to</var>)
                     in the following table such that <var>J</var> is an instance of <var>from</var>,
                     and <var>to</var> is <var>R</var>, then <var>J</var> is cast to type <var>R</var>.</p>
                     <table border="1" role="medium">
                        <caption>Implicit Casting</caption>
                        <thead>
                           <tr>
                              <th rowspan="1" colspan="1">from</th>
                              <th rowspan="1" colspan="1">to</th>
                           </tr>
                        </thead>
                        <tbody>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:decimal</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:double</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:double</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:decimal</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:decimal</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:float</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:float</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:decimal</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:float</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:double</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:double</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:float</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:string</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:anyURI</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:anyURI</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:string</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:hexBinary</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:base64Binary</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:base64Binary</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">xs:hexBinary</code>
                              </td>
                           </tr>
                        </tbody>
                     </table>
                     <note>
                        <p>The item type in the <var>to</var> column must match <var>R</var>
                        exactly; however, <var>J</var> may belong to a subtype of the type in the <var>from</var>
                        column.</p>
                        <p>For example, an <code nobreak="false">xs:NCName</code> will be cast to type <code nobreak="false">xs:anyURI</code>,
                        but an <code nobreak="false">xs:anyURI</code> will not be cast to type <code nobreak="false">xs:NCName</code>.</p>
                        <p>Similarly, an <code nobreak="false">xs:integer</code> will be cast to type <code nobreak="false">xs:double</code>,
                        but an <code nobreak="false">xs:double</code> will not be cast to type <code nobreak="false">xs:integer</code>.</p>
                     </note>
                  </item>
                  <item>
                     <p>If <var>R</var> is an <termref def="dt-singleton-enumeration-type"/>
                     and <var>J</var> is an instance of <code nobreak="false">xs:untypedAtomic</code>
                        or <code nobreak="false">xs:anyURI</code>, then <var>J</var> is cast to
                        type <code nobreak="false">xs:string</code>.</p>
                     <note>
                        <p>The effect of this rule, when taken in conjunction with the 
                        rules above regarding atomization and choice item types, is that 
                        when the required type is based on an <termref def="dt-enumeration-type"/>,
                        for example <code nobreak="false">enum("red", "green", "blue")*</code>, the supplied value can be, 
                        in this example:</p>
                        <ulist>
                           <item>
                              <p>The empty sequence.</p>
                           </item>
                           <item>
                              <p>The string <code nobreak="false">"red"</code>.</p>
                           </item>
                           <item>
                              <p>An untyped node whose string value is <code nobreak="false">"red"</code>.</p>
                           </item>
                           <item>
                              <p>A list-valued node whose typed value contains zero or more
                              strings (or <code nobreak="false">xs:anyURI</code> values), each of which is 
                              codepoint-equal to one of <code nobreak="false">"red"</code>, <code nobreak="false">"green"</code>,
                              or <code nobreak="false">"blue"</code>.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">xs:anyURI</code> value <code nobreak="false">"red"</code>.</p>
                           </item>
                           <item>
                              <p>An array with zero or more members each of which 
                              is codepoint-equal to one of <code nobreak="false">"red"</code>, <code nobreak="false">"green"</code>,
                              or <code nobreak="false">"blue"</code>.</p>
                           </item>
                           <item>
                              <p>A JNode whose <term>·jvalue·</term> property is any of the above.</p>
                           </item>
                        </ulist>
                     </note>
                  </item>
                  <item>
                     <p>If <var>R</var> is derived from some primitive atomic type <var>P</var>, 
                     then <var>J</var> is <term>relabeled</term> as an instance of <var>R</var> if it satisfies
                     all the following conditions:</p>
                     <ulist>
                        <item>
                           <p>
                              <var>J</var> is an instance of <var>P</var>.</p>
                        </item>
                        <item>
                           <p>
                              <var>J</var> is not an instance of <var>R</var>.</p>
                        </item>
                        <item>
                           <p>The <xtermref spec="DM40" ref="dt-datum"/> of <var>J</var> is 
                           within the value space of <var>R</var>.</p>
                        </item>
                     </ulist>
                     <p>Relabeling an atomic item changes the <termref def="dt-type-annotation"/> but not the 
                        <xtermref spec="DM40" ref="dt-datum"/>. For example, the
                        <code nobreak="false">xs:integer</code> value 3 can be relabeled as an instance of <code nobreak="false">xs:unsignedByte</code>, because
                        the datum is within the value space of <code nobreak="false">xs:unsignedByte</code>.</p>
                     <note>
                        <p>Relabeling is not the same as casting. For example, the <code nobreak="false">xs:decimal</code> value 10.1
                        can be cast to <code nobreak="false">xs:integer</code>, but it cannot be relabeled as <code nobreak="false">xs:integer</code>,
                        because its datum not within the value space of <code nobreak="false">xs:integer</code>.</p>
                     </note>
                     <note>
                        <p>The effect of this rule is that if, for example, a function parameter is declared
                        with an expected type of <code nobreak="false">xs:positiveInteger</code>, then a call that supplies the literal
                        value 3 will succeed, whereas a call that supplies -3 will fail.</p>
                        <p>This differs from previous versions of this specification, where both these calls would fail.</p>
                        <p>This change allows the arguments of existing functions to be defined with a
                           
                           more precise type. For example, the <code nobreak="false">$position</code> argument of <function>array:get</function>
                           
                           could be defined as <code nobreak="false">xs:positiveInteger</code> 
                           rather than <code nobreak="false">xs:integer</code>.</p>
                     </note>
                     <note>
                        <p>If <var>T</var>
                           is a union type with members <code nobreak="false">xs:negativeInteger</code> and 
                           <code nobreak="false">xs:positiveInteger</code> and the supplied value is the
                           sequence <code nobreak="false">(20, -20)</code>, then the effect of these rules 
                           is that the first item <code nobreak="false">20</code> is relabeled as type
                           <code nobreak="false">xs:positiveInteger</code> and the second item <code nobreak="false">-20</code>is relabeled as type 
                           <code nobreak="false">xs:negativeInteger</code>.</p>
                     </note>
                     <note>
                        <p>Promotion (for example of <code nobreak="false">xs:float</code> to <code nobreak="false">xs:double</code>)
                        occurs only when <var>T</var> is a primitive type.
                        Relabeling occurs only when <var>T</var> is a derived type. Promotion and relabeling are therefore
                        never combined.</p>
                     </note>
                     <note>
                        <p>The value space of a <termref def="dt-singleton-enumeration-type"/> 
                           such as <code nobreak="false">enum("green")</code> includes the <code nobreak="false">xs:string</code> value <code nobreak="false">"green"</code>; so if the
                     <code nobreak="false">xs:string</code> value <code nobreak="false">"green"</code> is supplied in a context where
                     the required type is <code nobreak="false">enum("red", "green", "blue")</code>, the value will be
                        accepted.</p>
                     </note>
                  </item>
                  <item>
                     <p>If <var>J</var> is a <xtermref spec="DM40" ref="dt-JNode"/> and does not
                        match <var>R</var>,
                     then each item in the <term>·jvalue·</term> of <var>J</var> is coerced to type <var>R</var>
                     by applying the coercion rules recursively.</p>
                     <note>
                        <p>For example, if <code nobreak="false">$A</code> is an array and the members
                     of the array are maps, then <code nobreak="false">$A/child::*</code> returns a sequence
                     of JNodes that encapsulate maps, and the average size of these maps can be obtained 
                     using the expression <code nobreak="false">avg($A/child::* ! map:size(.))</code>. The first
                     argument of <code nobreak="false">map:size</code> does not accept a JNode directly, but
                     it does (in effect) accept a JNode that encapsulates a map.</p>
                     </note>
                  </item>
                  <item diff="add" at="A">
                     <p>If <var>R</var> is an <nt def="doc-xquery40-ArrayType">ArrayType<!--$spec = xquery40--></nt> other than <code nobreak="false">array(*)</code> and <var>J</var>
                        is an array, then <var>J</var> is converted to a new array by converting
                        each member to the required member type by applying the coercion rules
                        recursively.</p>
                     <note>
                        <p>For example, if the required type is
                     <code nobreak="false">array(xs:double)</code> and the supplied value is
                        <code nobreak="false">[ 1, 2 ]</code>, the array is converted to
                        <code nobreak="false">[ 1e0, 2e0 ]</code>.</p>
                     </note>
                  </item>
                  <item diff="add" at="A">
                     <p>If <var>R</var> is a <nt def="doc-xquery40-MapType">MapType<!--$spec = xquery40--></nt> other than <code nobreak="false">map(*)</code> and <var>J</var>
                        is a map, then <var>J</var> is converted to a new map as follows:</p>
                     <olist>
                        <item>
                           <p>Each key in the supplied map is converted to the required
                           map key type by applying the coercion rules. If the resulting map would
                           contain duplicate keys, a type error is raised
                           <errorref class="TY" code="0004"/>.</p>
                        </item>
                        <item>
                           <p>The corresponding value is converted to the required
                           map value type by applying the coercion rules recursively.</p>
                        </item>
                        <item>
                           <p>The order of entries in the map remains unchanged.</p>
                        </item>
                     </olist>
                     <note>
                        <p>For example, if the required type is
                     <code nobreak="false">map(xs:string, xs:double)</code> and the supplied value is
                        <code nobreak="false">{ "x": 1, "y": 2 }</code>, the map is converted to
                        <code nobreak="false">{ "x": 1e0, "y": 2e0 }</code>.</p>
                     </note>
                     <note>
                        <p>Duplicate keys can occur if the value space of the target type
                        is more restrictive than the original type. For example, an error is raised
                        if the map <code nobreak="false">{ 1.2: 0, 1.2000001: 0 }</code>, which contains two keys
                        of type <code nobreak="false">xs:decimal</code>, is coerced to the type
                        <code nobreak="false">map(xs:float, xs:integer)</code>.</p>
                     </note>
                  </item>
                  <item diff="add" at="A">
                     <p>If <var>R</var> is a <nt def="doc-xquery40-RecordType">RecordType<!--$spec = xquery40--></nt> and <var>J</var> is a map, then <var>J</var> is converted
                        to a new map as follows:</p>
                     <olist>
                        <item>
                           <p>The keys in the supplied map are unchanged.</p>
                        </item>
                        <item>
                           <p>In any map entry whose key is equal to the
                        name of one of the field declarations in <var>R</var> (under the rules
                           of the <function>atomic-equal</function> function), the corresponding
                           value is converted to the required type defined by that field declaration, 
                           by applying the coercion rules recursively 
                           (but with XPath 1.0 compatibility mode treated as false).</p>
                        </item>
                        <item>
                           <p>Any map entry in the supplied map whose key is not equal to the name
                        of any of the field declarations in <var>R</var> (under the same rules) is
                        removed from the map.</p>
                        </item>
                        <item>
                           <p>The order of entries in the map is changed to match the order of the 
                              field declarations in <var>R</var>.</p>
                        </item>
                     </olist>
                     <note>
                        <p>For example, if the required type is
                     <code nobreak="false">record(longitude as xs:double, latitude as xs:double)</code> and the supplied value is 
                        <code nobreak="false">{ "latitude": 53.2, "longitude": 0, "altitude": 3_500 }</code>,
                        then the map is converted to <code nobreak="false">{ "longitude": 0.0e0, "latitude": 53.2e0 }</code>.</p>
                     </note>
                  </item>
                  <item>
                     <p>If <var>R</var> is a <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$spec = xquery40--></nt> and <var>J</var> is a function item, then <termref def="dt-function-coercion">function coercion</termref> is applied to <var>J</var>.</p>
                     <note>
                        <p>Function coercion applies even if <var>J</var> is already an instance
                        of <var>R</var>.</p>
                        <p>Maps and arrays are functions, so function coercion applies to them as well.</p>
                     </note>
                  </item>
                  <item>
                     <p> If, after the
		above conversions, the resulting item does not match
		the expected item type <var>R</var> according to the rules for <termref def="dt-sequencetype-matching">SequenceType
		Matching</termref>, a type error is
		raised <errorref class="TY" code="0004"/>.</p>
                     <note diff="add" at="Issue602">
                        <p>Under the general rules for type errors 
                           (see <specref ref="id-kinds-of-errors"/>), a processor
                        <rfc2119>may</rfc2119> report a type error during static
                        analysis if it will necessarily occur when the expression is evaluated.
                        For example, the function call <code nobreak="false">fn:abs("beer")</code>
                        will necessarily fail when evaluated, because the function requires
                        a numeric value as its argument; this <rfc2119>may</rfc2119> be detected and reported
                        as a static error.</p>
                     </note>
                  </item>
               </olist>
            </div3>
            <div3 id="id-implausible-coercions" diff="add" at="2023-06-01">
               <head>Implausible Coercions</head>
               <p>An expression is deemed to be
                     <termref def="dt-implausible"/>
                  <errorref class="TY" code="0006"/> if the static type of the expression, after applying
                     all necessary coercions, is <term>substantively disjoint</term>
                     with the required type <var>T</var>.</p>
               <p>
                  <termdef id="dt-substantively-disjoint"
                           term="substantively disjoint"
                           open="true">Two 
               <termref def="dt-sequence-type">sequence types</termref> are
                     deemed to be <term>substantively disjoint</term> if (a) neither is a subtype
                     of the other (see <specref ref="id-seqtype-subtype"/>) and 
                     (b) the only values that
                     are instances of both types are one or more of the following:</termdef>
               </p>
               <ulist>
                  <item>
                     <p>The empty sequence, <code nobreak="false">()</code>.</p>
                  </item>
                  <item>
                     <p>The <xtermref spec="DM40" ref="dt-empty-map"/>, <code nobreak="false">{}</code>.</p>
                  </item>
                  <item>
                     <p>The <xtermref spec="DM40" ref="dt-empty-array"/>, <code nobreak="false">[]</code>.</p>
                  </item>
               </ulist>
               <p role="closetermdef"/>
               <note>
                  <p>Examples of pairs of sequence types that are substantively disjoint
                        include:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">xs:integer*</code> and <code nobreak="false">xs:string*</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">map(xs:integer, node())</code> and <code nobreak="false">map(xs:string, node())</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array(xs:integer)</code> and <code nobreak="false">array(xs:string)</code>
                        </p>
                     </item>
                  </ulist>
               </note>
               <p>For example, supplying a value whose static type is <code nobreak="false">xs:integer*</code>
                     when the required type is <code nobreak="false">xs:string*</code> is <termref def="dt-implausible"/>,
                     because it can succeed only in the special case where the actual value supplied
                     is the empty sequence.</p>
               <note>
                  <p>The case where the supplied type and the required type are completely
                  disjoint (for example <code nobreak="false">map(*)</code> and <code nobreak="false">array(*)</code>) is covered
                  by the general rules for type errors: that case can always be reported as a static
                  error.</p>
               </note>
               <p>Examples of implausible coercions include the following:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">round(timezone-from-time($now))</code>. The result of <function>fn:timezone-from-time</function>
                  is of type <code nobreak="false">xs:dayTimeDuration?</code>, which is substantively disjoint with the required type
                  of <function>fn:round</function>, namely <code nobreak="false">xs:numeric?</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">function($x as xs:integer) as array(xs:string) { array { 1 to $x } }</code>. The type
                  of the function body is <code nobreak="false">array(xs:integer)</code>, which is substantively disjoint with the
                  required type <code nobreak="false">array(xs:string)</code>: the function can succeed only in the exceptional case
                  where the function body delivers an <xtermref spec="DM40" ref="dt-empty-array"/>.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-function-coercion">
               <head>Function Coercion</head>
               <changes>
                  <change>
                     Function coercion now allows a function with arity <var>N</var> to be supplied where a function of arity 
                     greater than <var>N</var> is expected. For example this allows the function <code nobreak="false">true#0</code> 
                     to be supplied where a predicate function is required.
                  </change>
                  <change issue="1020" PR="1023 1128" date="2024-04-09">
                     It has been clarified that function coercion applies even when the supplied function item
                     matches the required function type. This is to ensure that arguments supplied when calling
                     the function are checked against the signature of the required function type, which might
                     be stricter than the signature of the supplied function item.
                  </change>
               </changes>
               <p>
        Function coercion is a transformation applied to <termref def="dt-function-item">function items</termref> during application of the
        <termref def="dt-coercion-rules">coercion rules</termref>.
        <termdef term="function coercion" id="dt-function-coercion">
                     <term>Function coercion</term> wraps a <termref def="dt-function-item"/>
        in a new function whose signature is the same as the expected type.
        This effectively delays the checking
        of the argument and return types
        until the function is called.</termdef>
               </p>
               <p>Given a function <var>F</var>, and an expected function type <var>T</var>,
                  <termref def="dt-function-coercion">function coercion</termref>
	proceeds as follows:</p>
               <olist>
                  <item>
                     <p>If <var>F</var> has higher arity than <var>T</var>,
                     a type error is raised <errorref class="TY" code="0004"/>
                     </p>
                  </item>
                  <item diff="add" at="A">
                     <p>If <var>F</var> has lower arity than <var>T</var>,
                     then <var>F</var> is wrapped in a new function that declares and ignores the
                  additional argument; the following steps are then applied to this new function.</p>
                     <p>For example, if <var>T</var> is <code nobreak="false">function(node(), xs:boolean) as xs:string</code>,
                  and the supplied function is <function>fn:name#1</function>, then the supplied function is effectively
                  replaced by <code nobreak="false">function($n as node(), $b as xs:boolean) as xs:string { fn:name($n) }</code>
                     </p>
                     <note>
                        <p>This mechanism makes it easier to design versatile and extensible higher-order functions. 
                     For example, in previous versions of this specification, the second argument of
                     the <function>fn:filter</function> function expected an argument of type 
                     <code nobreak="false">function(item()) as xs:boolean</code>. This has now been extended to
                     <code nobreak="false">function(item(), xs:integer) as xs:boolean</code>, but existing code continues
                     to work, because callback functions that are not interested in the value of the second
                     argument simply ignore it.                    
                  </p>
                     </note>
                  </item>
                  <item>
                     <p>A type error is raised <errorref class="TY" code="0004"/> 
                        if, for any parameter type, or for the result type, the 
                        relevant type in the signature of the supplied function and the relevant type
                        in the expected function type are <termref def="dt-substantively-disjoint"/>.
                     </p>
                     <p>For example, the types <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:string</code>
                     are substantively disjoint, so a function with signature <code nobreak="false">function(xs:integer) as xs:boolean</code>
                        cannot be supplied where the expected type is <code nobreak="false">function(xs:string) as xs:boolean</code>.</p>
                  </item>
                  <item>
                     <p>Function coercion then
        returns a new <termref def="dt-function-item"/>
        with the following properties
        (as defined in <xspecref spec="DM40" ref="function-items"/>):

        <ulist>
                           <item>
                              <p>
                                 <term>name</term>:
            The name of <var>F</var>
                                 <phrase diff="add" at="B">(if not absent)</phrase>.
          </p>
                           </item>
                           <item>
                              <p diff="add" at="2023-05-25">
                                 <term>identity</term>: A new function
              identity distinct from the identity of any other function item.</p>
                              <note>
                                 <p>See also <specref ref="id-function-identity"/>.</p>
                              </note>
                           </item>
                           <item>
                              <p>
                                 <term>signature</term>:
            <code nobreak="false">Annotations</code> is set to the annotations of <var>F</var>. <code nobreak="false">TypedFunctionType</code> is set to the expected type.
          </p>
                           </item>
                           <item>
                              <p>
                                 <term>implementation</term>:
            In effect,
            a <code nobreak="false">FunctionBody</code> that calls <var>F</var>,
            passing it the parameters of this new function,
            in order.
          </p>
                           </item>
                           <item>
                              <p>
                                 <term>nonlocal variable bindings</term>:
            An empty mapping.
          </p>
                           </item>
                        </ulist>
                     </p>
                  </item>
               </olist>
               <!--<p>
        If the result of invoking the new function would
        necessarily result in a type error, that
        error may be raised during
                  <termref
                     def="dt-function-coercion"
                  >function coercion</termref>. It is implementation dependent whether this
        happens or not.
      </p>-->
               <p>
        These rules have the following consequences:

        <ulist>
                     <item>
                        <p>SequenceType matching of the function’s arguments and result are delayed until that function is called.
          </p>
                     </item>
                     <item>
                        <p>When the coerced function is called, the supplied arguments must match the parameter
              typed defined in <var>T</var>; it is not sufficient to match the parameter types defined
              in <var>F</var>.</p>
                     </item>
                     <item>
                        <p>
                           The <termref def="dt-coercion-rules">coercion rules</termref> rules applied to the function’s arguments and result are defined by the SequenceType
            it has most recently been coerced to. Additional coercion rules could apply when the wrapped function
            is called.
          </p>
                     </item>
                     <item>
                        <p>
            If an implementation has static type information about a function, that can be used to type check the
            function’s argument and return types during static analysis.
          </p>
                     </item>
                     <item>
                        <p>When function coercion is applied to a map or an array, the resulting function is not
           a map or array, and cannot be used as such. For example, the expression </p>
                        <eg xml:space="preserve">let $f as function(xs:integer) as xs:boolean := { 0: false(), 1: true() }
return $f?0</eg>
                        <p>raises a type error, because a lookup expression requires the left hand
           operand to be a map or array, and <code nobreak="false">$f</code> is neither.</p>
                     </item>
                     <item>
                        <p>When function types are used as alternatives in a <termref def="dt-choice-item-type"/>,
                 the supplied function is coerced to the first alternative for which coercion does
                 not raise a type error. In this situation it is important to write the alternatives
                 in order, with the most specific first. </p>
                     </item>
                  </ulist>
               </p>
               <p role="xquery">
      For instance, consider the following query:
      <eg role="parse-test" xml:space="preserve">
declare function local:filter(
  $s as item()*, 
  $p as function(xs:string) as xs:boolean
) as item()* {
  $s[$p(.)]
};
let $f := function($a) { starts-with($a, "E") }
return local:filter(("Ethel", "Enid", "Gertrude"), $f)
      </eg>
               </p>
               <p role="xquery">
        The function <code nobreak="false">$f</code> has a static type of <code nobreak="false">function(item()*) as item()*</code>. When the <code nobreak="false">local:filter()</code> function
        is called, the following occurs to the function:

        <olist>
                     <item>
                        <p>
                           The <termref def="dt-coercion-rules">coercion rules</termref> result in applying 
                           <termref def="dt-function-coercion">function coercion</termref> to 
            <code nobreak="false">$f</code>,
            wrapping $f in a new function (<code nobreak="false">$p</code>)
            with the signature <code nobreak="false">function(xs:string) as xs:boolean</code>.
          </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$p</code> is matched against the SequenceType of <code nobreak="false">function(xs:string) as xs:boolean</code>, and succeeds.
          </p>
                     </item>
                     <item>
                        <p>
                           When <code nobreak="false">$p</code> is called inside the predicate, <termref def="dt-coercion-rules">coercion</termref> 
                           and SequenceType matching rules are applied to the context value argument,
            resulting in an <code nobreak="false">xs:string</code> value or a type error.
          </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$f</code> is called with the <code nobreak="false">xs:string</code>, which returns an <code nobreak="false">xs:boolean</code>.
          </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$p</code> applies <termref def="dt-coercion-rules">coercion rules</termref> to the result sequence from <code nobreak="false">$f</code>, 
                           which already matches its declared return type of <code nobreak="false">xs:boolean</code>.
          </p>
                     </item>
                     <item>
                        <p>
            The <code nobreak="false">xs:boolean</code> is returned as the result of <code nobreak="false">$p</code>.
          </p>
                     </item>
                  </olist>
               </p>
               <note>
                  <p>
                     The semantics of <termref def="dt-function-coercion">function coercion</termref> are specified in terms of wrapping the functions.
        Static typing may be able to reduce the number of places where this is actually necessary.
        However, it cannot be assumed that because a supplied function is an instance of the required
        function type, no function coercion is necessary: the supplied function might not perform
        all required checks on the types of its arguments.
      </p>
               </note>
               <p>Since maps and arrays are also functions in XQuery 4.0, 
                  <termref def="dt-function-coercion">function coercion</termref> applies to them as well.

        For instance, consider the following expression:
      </p>
               <eg role="parse-test" xml:space="preserve">
let $m := {
  "Monday" : true(),
  "Wednesday" : false(),
  "Friday" : true()
}
let $days := ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
return filter($days, $m)
      </eg>
               <p>
        The map <code nobreak="false">$m</code> is an instance of 
                  <code nobreak="false">function(xs:anyAtomicType?) as item()*</code>. 
                  When the <code nobreak="false">fn:filter()</code> function is called, the following 
                  occurs to the map:

<olist>
                     <item>
                        <p>The map <code nobreak="false">$m</code> is treated as a function equivalent to <code nobreak="false">map:get($m, ?)</code>.</p>
                     </item>
                     <item>
                        <p>The <termref def="dt-coercion-rules">coercion rules</termref> result in applying 
                           <termref def="dt-function-coercion">function coercion</termref> 
                           to this function, wrapping it in a new function (<var>M'</var>) with the 
                           signature <code nobreak="false">function(item(), xs:integer) as xs:boolean</code>.</p>
                     </item>
                     <item>
                        <p>When <var>M'</var> is called by <code nobreak="false">fn:filter()</code>, <termref def="dt-coercion-rules">coercion</termref> 
                           and SequenceType matching rules are applied to the argument, 
                           resulting in an <code nobreak="false">item()</code> value 
                           (<code nobreak="false">$a</code>) or a type error.</p>
                     </item>
                     <item>
                        <p>
                           The function <code nobreak="false">map:get($m, ?)</code> is called with <code nobreak="false">$a</code>
                           as the argument; this returns either an <code nobreak="false">xs:boolean</code> or the empty sequence
                           (call the result <var>R</var>).</p>
                     </item>
                     <item>
                        <p>
                           The wrapper function <code nobreak="false">$p</code> applies the <termref def="dt-coercion-rules"/>
                              to <var>R</var>. If <var>R</var> is an <code nobreak="false">xs:boolean</code> the matching succeeds. 
                              When it is the empty sequence (in particular, <code nobreak="false">$m</code> does not contain a 
                           key for <code nobreak="false">"Tuesday"</code>), a type error is raised <errorref class="TY" code="0004"/>, since the expected type is <code nobreak="false">xs:boolean</code>, 
                           which does not allow the empty sequence.</p>
                     </item>
                  </olist>
               </p>
               <p>Consider the following expression:
      </p>
               <eg role="parse-test" xml:space="preserve">

let $m := {
   "Monday" : true(),
   "Wednesday" : false(),
   "Friday" : true(),
}
let $days := ("Monday", "Wednesday", "Friday")
return filter($days, $m)
      </eg>
               <p>In this case the result of the expression is the sequence <code nobreak="false">("Monday", "Friday")</code>.
                  But if the input sequence included the string <code nobreak="false">"Tuesday"</code>, the filter operation
                  would fail with a type error.
               </p>
               <note diff="add" at="issue1020">
                  <p>Function coercion applies even if the supplied function matches the required type.</p>
                  <p>For example, consider this case:</p>
                  <eg role="parse-test" xml:space="preserve">
declare function local:filter(
  $s as item()*, 
  $p as function(xs:string) as xs:boolean
) as item()* {
  $s[$p(.)]
};

let $f := function($a) { $a mod 2 = 0 }
return local:filter(1 to 10, $f)
      </eg>
                  <p>Here the supplied function <code nobreak="false">$f</code> is an instance of the required type,
                  because its signature defaults the argument type to <code nobreak="false">item()*</code>, which
                  is a supertype of <code nobreak="false">xs:string</code>. The expression <code nobreak="false">$s[$p(.)]</code>
                  could in principle succeed. However, function coercion ensures that the supplied function 
                  is wrapped in a function that requires the argument to be of type <code nobreak="false">xs:string</code>,
                  so the call fails with a type error when the wrapping function is invoked supplying an
                  <code nobreak="false">xs:integer</code> as the argument.</p>
                  <p role="xquery">This has the consequence that in XQuery 4.0, there is a backwards
                     incompatibility introduced because coercion rules
                  now apply to global variable declarations (<code nobreak="false">declare variable</code>) and
                  local variable bindings (for example <code nobreak="false">let</code> clauses). Previously
                  the following would execute without error:</p>
                  <eg role="xquery" xml:space="preserve">let $f as function(xs:integer) as item()* := function($x) { $x + 1 }
return $f(12.3)</eg>
                  <p role="xquery">With XQuery 4.0, as a consequence of function coercion,
                     this fails with a type error because the
                  argument supplied in the function call is not of type <code nobreak="false">xs:integer</code>.</p>
               </note>
            </div3>
            <div3 id="id-coercion-examples">
               <head>Examples of Coercions</head>
               <p>This section illustrates the effect of the coercion rules with examples.</p>
               <example id="eg-coercion-to-string">
                  <head>Coercion to <code nobreak="false">xs:string</code>
                  </head>
                  <p>Consider the case where the required type (of a variable, or a function argument)
                  is <code nobreak="false">xs:string</code>. For example, the second argument of <function>fn:matches</function>,
                  which expects a regular expression. The table below illustrates the values that might be supplied, and
                  the coercions that are applied.</p>
                  <table role="medium">
                     <thead>
                        <tr>
                           <th align="left" rowspan="1" colspan="1">Supplied Value</th>
                           <th align="left" rowspan="1" colspan="1">Coercion</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">"[0-9]"</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>None; the supplied value is an instance of the required type.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">default-language()</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>None; the supplied value is an instance of <code nobreak="false">xs:language</code>, which
                              is a subtype of the required type <code nobreak="false">xs:string</code>.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">&lt;a&gt;[0-9]&lt;/a&gt;</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied element node is atomized. Unless it has been schema-validated,
                           the typed value will be an instance of <code nobreak="false">xs:untypedAtomic</code>, which
                           is accepted when the required type is <code nobreak="false">xs:string</code>.</p>
                              <p>Supplying an element whose type annotation is (say) <code nobreak="false">xs:date</code> 
                                 will fail with a type error.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">xs:anyURI("urn:dummy")</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>Supplying an instance of <code nobreak="false">xs:anyURI</code> where the expected type
                              is <code nobreak="false">xs:string</code> is permitted; this is one of the pairs of types
                           where implicit casting is allowed.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">["a|b"]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>Supplying an array holding a single string succeeds, because the rules cause the
                              array to be atomized, and the value after atomization is a single string.</p>
                              <p>Supplying an array holding multiple strings would fail.</p>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </example>
               <example id="eg-coercion-to-decimal">
                  <head>Coercion to <code nobreak="false">xs:decimal?</code>
                  </head>
                  <p>Consider the case where the required type (of a variable, or a function argument)
                     is <code nobreak="false">xs:decimal?</code>. For example, the first argument of <function>fn:seconds</function>,
                     which expects a decimal number of seconds. The table below illustrates the values that might be supplied, and
                     the coercions that are applied.</p>
                  <table role="medium">
                     <thead>
                        <tr>
                           <th align="left" rowspan="1" colspan="1">Supplied Value</th>
                           <th align="left" rowspan="1" colspan="1">Coercion</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">12.4</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>None; the supplied value is an instance of the required type.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">()</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>None; the empty sequence is an instance of the required type.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">42</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>None; the supplied value is an instance of <code nobreak="false">xs:integer</code>,
                              which is a subtype of the required type.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">math:pi()</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is an instance of <code nobreak="false">xs:double</code>,
                              which can be converted to <code nobreak="false">xs:decimal</code> under the coercion rules.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">("a", "b")[.="c"]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is the empty sequence, which is a valid
                              instance of the required type <code nobreak="false">xs:decimal?</code>. However,
                           the processor may (optionally) reject this as an implausible coercion,
                           on the grounds that it can only succeed in one special case, namely
                           where the filter expression selects no values. </p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">(1.5, 2.5, 3.5)</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>A type error is raised.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">&lt;a&gt;3.14159&lt;/a&gt;</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The element node is atomized; unless it has been schema-validated, the
                              result will be <code nobreak="false">"3.14159"</code> as an instance of <code nobreak="false">xs:untypedAtomic</code>.
                             This is converted to an instance of <code nobreak="false">xs:decimal</code> following the rules
                           of the <code nobreak="false">cast as</code> operator.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">[1.5]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The array is atomized, and the result is a valid instance of the required
                           type <code nobreak="false">xs:decimal?</code>
                              </p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">[]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The array is atomized, and the result is the empty sequence, which is a valid instance of the required
                              type <code nobreak="false">xs:decimal?</code>
                              </p>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </example>
               <example id="eg-coercion-to-positive-integer">
                  <head>Coercion to <code nobreak="false">xs:positive-integer</code>
                  </head>
                  <p>Consider the case where the required type (of a variable, or a function argument)
                     is <code nobreak="false">xs:positive-integer</code>. The table below illustrates the values that might be supplied, and
                     the coercions that are applied.</p>
                  <table role="medium">
                     <thead>
                        <tr>
                           <th align="left" rowspan="1" colspan="1">Supplied Value</th>
                           <th align="left" rowspan="1" colspan="1">Coercion</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">12</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is of type <code nobreak="false">xs:integer</code>. Because the supplied value and
                              the required type, <code nobreak="false">xs:positiveInteger</code>, both come under the primitive
                           type <code nobreak="false">xs:decimal</code>, and the value <code nobreak="false">12</code> is within the value space
                           of <code nobreak="false">xs:positiveInteger</code>, the value is relabeled as an <code nobreak="false">xs:positiveInteger</code>
                           and the call succeeds.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">12.1</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>This fails with a type error, because the <code nobreak="false">xs:decimal</code> value <code nobreak="false">12.1</code>
                              is not a value in the value space of <code nobreak="false">xs:positiveInteger</code>. This is so even though
                           casting to <code nobreak="false">xs:positiveInteger</code> would succeed.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">math:pi()</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>This fails with a type error. A value of type <code nobreak="false">xs:double</code> is accepted
                           where the required type is <code nobreak="false">xs:decimal</code> or <code nobreak="false">xs:float</code>,
                           but not where it is <code nobreak="false">xs:positiveInteger</code>.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">&lt;a&gt;1200&lt;/a&gt;</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied element node is atomized. If the element has not been schema-validated,
                           the result will be an <code nobreak="false">xs:untypedAtomic</code> item, which is successfully cast to the
                           required type <code nobreak="false">xs:positiveInteger</code>. If the element has been validated against a schema,
                           then coercion succeeds if the typed value would itself be acceptable, for example if it
                           is an <code nobreak="false">xs:positiveInteger</code>, or some other <code nobreak="false">xs:decimal</code> within the value space
                           of <code nobreak="false">xs:positiveInteger</code>.</p>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </example>
               <example id="eg-coercion-to-union">
                  <head>Coercion to a union type</head>
                  <p>Consider the first parameter of the function <function>fn:char</function>, whose declared
                  type is <code nobreak="false">(xs:string | xs:positiveInteger)</code>. The rules are the same
                  as if it were a union typed declared in an imported schema.</p>
                  <table role="medium">
                     <thead>
                        <tr>
                           <th align="left" rowspan="1" colspan="1">Supplied Value</th>
                           <th align="left" rowspan="1" colspan="1">Coercion</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">"amp"</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is of type <code nobreak="false">xs:string</code>, which is one of the allowed
                           types. The call therefore succeeds.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">"#"</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is of type <code nobreak="false">xs:string</code>, which is one of the allowed
                              types. As far as the coercion rules are concerned, the call therefore succeeds. Under the
                              semantic rules for the <function>fn:char</function> function, however, this value is not accepted;
                              a dynamic error (as distinct from a type error) is therefore raised.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">0x25</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is of type <code nobreak="false">xs:integer</code>. Although this is not one of the allowed
                              types, it is acceptable because coercion of the value to type <code nobreak="false">xs:positiveInteger</code>
                              succeeds. The value is relabeled as an instance of <code nobreak="false">xs:positiveInteger</code>.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">&lt;a&gt;0x25&lt;/a&gt;</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied element node is atomized. Assuming that the node has not been schema-validated,
                              the result is an instance of <code nobreak="false">xs:untypedAtomic</code>. The member types of the choice
                              are tested in order. Conversion to <code nobreak="false">xs:string</code> with the value "0x25" succeeds, so 
                              the <function>fn:char</function> function is called supplying this string; but the function rejects this
                              string as semantically invalid. The same would happen if the value were, say, &lt;a&gt;37&lt;/a&gt;.
                              Supplying such a value requires an explicit cast, for example <code nobreak="false">fn:char( xs:positiveInteger( ./a ))</code>.</p>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </example>
               <example id="eg-coercion-to-choice">
                  <head>Coercion to a choice type</head>
                  <p>Suppose the required type is <code nobreak="false">(record(x as xs:decimal, y as xs:decimal, *) | record(size as enum("S", "M", "L", "XL"), *))</code>.</p>
                  <table role="medium">
                     <col width="40%" span="1"/>
                     <col width="60%" span="1"/>
                     <thead>
                        <tr>
                           <th align="left" rowspan="1" colspan="1">Supplied Value</th>
                           <th align="left" rowspan="1" colspan="1">Coercion</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">{ "x": 1, "y": 2, "z": 3 }</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is an instance of the first record type: no coercion is necessary.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">{ "size": "M" }</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is an instance of the second record type: no coercion is necessary.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">{ "x": 1, "y": 2, "size": "XL" }</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is an instance of both record types: no coercion is necessary.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">{ "x": 1e0, "y": 2e0, "size": "XL" }</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is not an instance of the first record type because the fields are of
                              type <code nobreak="false">xs:double</code> rather than <code nobreak="false">xs:decimal</code>. It is however an instance
                              of the second record type. It is therefore accepted <emph>as is</emph>; the fields
                           <code nobreak="false">x</code> and <code nobreak="false">y</code> are not converted from <code nobreak="false">xs:double</code> to
                           <code nobreak="false">xs:decimal</code>.</p>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">{ "x": 1e0, "y": 2e0, "size": "XXL" }</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <p>The supplied value is not an instance of the first record type because the fields are of
                              type <code nobreak="false">xs:double</code> rather than <code nobreak="false">xs:decimal</code>, and it is not an instance
                              of the second record type because the <code nobreak="false">size</code> value does not match the enumeration
                              type. Coercion is therefore attempted to the first record type, and succeeds. The <code nobreak="false">x</code>
                           and <code nobreak="false">y</code> fields are coerced to <code nobreak="false">xs:decimal</code>, and the <code nobreak="false">size</code> field
                           is accepted <emph>as is</emph>.</p>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </example>
            </div3>
         </div2>
         <div2 id="id-predefined-types">
            <head>Schema Types</head>
            <p>
               <termdef id="dt-schema-type" term="schema type">A <term>schema type</term>
            is a complex type or simple type as defined in the <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/> specifications, including built-in types as well as user-defined types.</termdef>
            </p>
            <p>Every schema type is either a <term>complex type</term> or a
            <term>simple type</term>; simple types are further subdivided into <term>list types</term>, <term>union
               types</term>, and <term>atomic types</term> (see <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/> for definitions and explanations of these terms.)</p>
            <p>A schema type can appear as a type annotation on an
            element or attribute node. The type annotation on an element node can be
            a complex type or a simple type; the type annotation on an attribute node
            is always a simple type. Non-instantiable types such as <code nobreak="false">xs:NOTATION</code> or
            <code nobreak="false">xs:anyAtomicType</code> never appear as type annotations, but their derived
            types can be so used. Union types never appear as type annotations; when
            an element or attribute is validated against a union type, the resulting
            type annotation will be one of the types in the transitive membership of 
            the union type.</p>
            <p>
               <termdef id="dt-atomic-type" term="atomic type">An <term>atomic type</term>
            is a simple <termref def="dt-schema-type"/> whose 
            <xtermref spec="XS11-1" ref="std-variety">{variety}</xtermref>
            is <code nobreak="false">atomic</code>.</termdef>
            </p>
            <p>An <term>atomic type</term> is either a built-in atomic
            type (defined either in the XSD specification or in this specification), or
            it is a user-defined atomic type included in an imported schema.</p>
            <p>The schema types defined in  <xspecref spec="DM40" ref="types-predefined"/> are summarized below.</p>
            <p role="xquery">The <termref def="dt-is-types">in-scope schema types</termref> in the <termref def="dt-static-context">static context</termref>
            are initialized with certain predefined schema types,
            including the built-in schema types in the namespace
            <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>,
            which has the predefined namespace prefix
            <code nobreak="false">xs</code>.  The schema types in this namespace are defined in <bibref ref="XMLSchema10"/> or  <bibref ref="XMLSchema11"/>
            and augmented by additional types defined in <bibref ref="xpath-datamodel-40"/>.  Element and attribute
            declarations in the <code nobreak="false">xs</code> namespace are
            not implicitly included in the static context. The schema types defined in  <bibref ref="xpath-datamodel-40"/> are summarized below.</p>
            <olist>
               <item>
                  <p>
                     <termdef term="xs:untyped" id="dt-untyped">
                        <code nobreak="false">xs:untyped</code> is  used as the <termref def="dt-type-annotation">type annotation</termref> of an element node that has not been validated, or has been validated in <code nobreak="false">skip</code> mode.</termdef> 
                  No predefined schema types are derived from <code nobreak="false">xs:untyped</code>.</p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-untypedAtomic" term="xs:untypedAtomic">
                        <code nobreak="false">xs:untypedAtomic</code>
                     is an <termref def="dt-atomic-type"/> that is used to denote untyped atomic data, 
                     such as text that has not been assigned a more specific type.</termdef> 
                  An attribute that has been validated in <code nobreak="false">skip</code> mode is represented in the <termref def="dt-datamodel">data model</termref> by an attribute node with the <termref def="dt-type-annotation">type annotation</termref>
                     <code nobreak="false">xs:untypedAtomic</code>. No predefined schema types are derived from <code nobreak="false">xs:untypedAtomic</code>.</p>
               </item>
               <item>
                  <p>
                     <termdef term="xs:dayTimeDuration" id="dt-dayTimeDuration">
                        <code nobreak="false">xs:dayTimeDuration</code> is derived by restriction from <code nobreak="false">xs:duration</code>. The  lexical representation of <code nobreak="false">xs:dayTimeDuration</code>
                     is restricted to contain only day, hour, minute, and second
                     components.</termdef>
                  </p>
               </item>
               <item>
                  <p>
                     <termdef term="xs:yearMonthDuration" id="dt-yearMonthDuration">
                        <code nobreak="false">xs:yearMonthDuration</code> is derived by restriction from <code nobreak="false">xs:duration</code>. The lexical representation of <code nobreak="false">xs:yearMonthDuration</code> is
                     restricted to contain only year and month
                     components.</termdef>
                  </p>
               </item>
               <item>
                  <p>
                     <termdef term="xs:anyAtomicType" id="dt-anyAtomicType">
                        <code nobreak="false">xs:anyAtomicType</code> is an <termref def="dt-atomic-type"/> 
                     that includes all atomic items (and no values that
                     are not atomic). Its base type is
                     <code nobreak="false">xs:anySimpleType</code> from which all simple types, including atomic,
                     list, and union types, are derived. All primitive atomic types, such as
                     <code nobreak="false">xs:decimal</code> and <code nobreak="false">xs:string</code>, have <code nobreak="false">xs:anyAtomicType</code> as their base type.</termdef>
                  </p>
                  <note>
                     <p>
                        <code nobreak="false">xs:anyAtomicType</code>  will not appear as the type of an actual value in an <termref def="dt-data-model-instance">XDM instance</termref>.</p>
                  </note>
               </item>
               <item>
                  <p>
                     <termdef term="xs:error" id="dt-xs-error">
                        <code nobreak="false">xs:error</code> is a simple type with no value space.  It is defined in <xspecref spec="XS11-1" ref="xsd-error"/> and  can be used in the <specref ref="id-sequencetype-syntax"/> to raise errors.</termdef>
                  </p>
               </item>
            </olist>
            <p>The relationships among the schema types in the <code nobreak="false">xs</code> namespace are illustrated in Figure 2. A more complete description of the XQuery 4.0 type hierarchy can be found in 
            <xspecref spec="FO40" ref="datatypes"/>.</p>
            <graphic xmlns:xlink="http://www.w3.org/1999/xlink"
                     source="types.jpg"
                     alt="Type Hierarchy Diagram"
                     xlink:type="simple"
                     xlink:show="embed"
                     xlink:actuate="onLoad"/>
            <p>Figure 2: Hierarchy of Schema Types used in XQuery 4.0.</p>
         </div2>
      </div1>
      <div1 id="id-expressions">
         <head>Expressions</head>
         <p>This section discusses each of the basic kinds of expression. Each kind of expression has a name such as <code nobreak="false">PathExpr</code>, which is introduced on the left side of the grammar production that defines the expression. Since XQuery 4.0 is a composable language, each kind of expression is defined in terms of other expressions whose operators have a higher precedence. In this way, the precedence of operators is represented explicitly in the grammar.</p>
         <p>The order in which expressions are discussed in this document does not reflect the order of operator precedence. In general, this document introduces the simplest kinds of expressions first, followed by more complex expressions.  For the complete grammar, see Appendix [<specref ref="nt-bnf"/>].</p>
         <p>
            <phrase role="xquery">
               <termdef id="dt-query" term="query">A <term>query</term> consists of one or more <termref def="dt-module">modules</termref>.</termdef>  If a query is executable, one of its modules has a <termref def="dt-queryBody">Query Body</termref>  containing an expression whose value is the result of the query. An expression is represented in the XQuery grammar by the symbol <nt def="doc-xquery40-Expr">Expr<!--$spec = xquery40--></nt>.</phrase>
         </p>
         <scrap role="xquery" headstyle="show">
            <prod id="doc-xquery40-Expr">
               <lhs>Expr</lhs>
               <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
            </prod>

            <prod id="doc-xquery40-Expr-ExprSingle">
               <lhs>ExprSingle</lhs>
               <rhs>
                  <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>
         </scrap>
         <scrap headstyle="show">
            <prod id="doc-xquery40-ExprSingle">
               <lhs>ExprSingle</lhs>
               <rhs>
                  <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                  <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-ExprSingle-FLWORExpr">
               <lhs>FLWORExpr</lhs>
               <rhs>
                  <nt def="prod-xquery40-InitialClause">InitialClause<!--$idref_lang_part = xquery40- --></nt>
                  <nt def="prod-xquery40-IntermediateClause">IntermediateClause<!--$idref_lang_part = xquery40- --></nt>*  <nt def="prod-xquery40-ReturnClause">ReturnClause<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-ExprSingle-QuantifiedExpr">
               <lhs>QuantifiedExpr</lhs>
               <rhs>("some"  |  "every")  (<nt def="prod-xquery40-QuantifierBinding">QuantifierBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")  "satisfies"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-ExprSingle-SwitchExpr">
               <lhs>SwitchExpr</lhs>
               <rhs>"switch"  <nt def="prod-xquery40-SwitchComparand">SwitchComparand<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-SwitchCases">SwitchCases<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedSwitchCases">BracedSwitchCases<!--$idref_lang_part = xquery40- --></nt>)</rhs>
            </prod>

            <prod id="doc-xquery40-ExprSingle-TypeswitchExpr">
               <lhs>TypeswitchExpr</lhs>
               <rhs>"typeswitch"  "("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  ")"  (<nt def="prod-xquery40-TypeswitchCases">TypeswitchCases<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedTypeswitchCases">BracedTypeswitchCases<!--$idref_lang_part = xquery40- --></nt>)</rhs>
            </prod>

            <prod id="doc-xquery40-ExprSingle-IfExpr">
               <lhs>IfExpr</lhs>
               <rhs>"if"  "("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  ")"  (<nt def="prod-xquery40-UnbracedActions">UnbracedActions<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedAction">BracedAction<!--$idref_lang_part = xquery40- --></nt>)</rhs>
            </prod>

            <prod id="doc-xquery40-ExprSingle-TryCatchExpr">
               <lhs>TryCatchExpr</lhs>
               <rhs>
                  <nt def="prod-xquery40-TryClause">TryClause<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-CatchClause">CatchClause<!--$idref_lang_part = xquery40- --></nt>+  <nt def="prod-xquery40-FinallyClause">FinallyClause<!--$idref_lang_part = xquery40- --></nt>?)  |  <nt def="prod-xquery40-FinallyClause">FinallyClause<!--$idref_lang_part = xquery40- --></nt>)</rhs>
            </prod>

            <prod id="doc-xquery40-ExprSingle-OrExpr">
               <lhs>OrExpr</lhs>
               <rhs>
                  <nt def="prod-xquery40-AndExpr">AndExpr<!--$idref_lang_part = xquery40- --></nt>  ("or"  <nt def="prod-xquery40-AndExpr">AndExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
            </prod>
         </scrap>
         <p>The XQuery 4.0 operator that has lowest precedence is the <termref def="dt-comma-operator">comma operator</termref>, which is used to combine two operands to form a sequence. 
         As shown in the grammar, a general expression (<nt def="doc-xquery40-Expr">Expr<!--$spec = xquery40--></nt>) can consist of multiple <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt> operands, separated by commas.</p>
         <p>The name <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt> denotes an expression that does not contain a top-level <termref def="dt-comma-operator">comma operator</termref> (despite its name, an <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt> may evaluate to a sequence containing more than one item.)</p>
         <p>The symbol <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt> is used in various places in the grammar where an expression 
         is not allowed to contain a top-level comma. For example, each of the arguments 
         of a function call must be a <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt>, because commas are 
         used to separate the arguments of a function call.</p>
         <p>After the comma, the expressions that have next lowest precedence are
<phrase role="xquery">
               <nt def="doc-xquery40-FLWORExpr">FLWORExpr<!--$spec = xquery40--></nt>,</phrase>
            <nt def="doc-xquery40-QuantifiedExpr">QuantifiedExpr<!--$spec = xquery40--></nt>,
<phrase role="xquery">
               <nt def="doc-xquery40-SwitchExpr">SwitchExpr<!--$spec = xquery40--></nt>, <nt def="doc-xquery40-TypeswitchExpr">TypeswitchExpr<!--$spec = xquery40--></nt>, </phrase>
            <nt def="doc-xquery40-IfExpr">IfExpr<!--$spec = xquery40--></nt>,
<phrase role="xquery">
               <nt def="doc-xquery40-TryCatchExpr">TryCatchExpr<!--$spec = xquery40--></nt>, </phrase>
and <nt def="doc-xquery40-OrExpr">OrExpr<!--$spec = xquery40--></nt>. Each of these expressions is described in a separate section of this document.</p>
         <div2 id="comments">
            <head>Comments</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-Comment">
                  <lhs>Comment</lhs>
                  <rhs>"(:"  (<nt def="prod-xquery40-CommentContents">CommentContents<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Comment">Comment<!--$idref_lang_part = xquery40- --></nt>)*  ":)"</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
                  <com>
                     <loc href="#parse-note-comments">gn: comments</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-Comment-CommentContents">
                  <lhs>CommentContents</lhs>
                  <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>+ - (Char* ('(:' | ':)') Char*))</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>Comments may be used to provide information relevant to programmers who read <phrase role="xquery">a query, either in the <termref def="dt-prolog">Prolog</termref> or in the <termref def="dt-queryBody">Query Body</termref>
               </phrase>
            . Comments are lexical constructs only, and do not affect  <phrase role="xquery">query</phrase>
             processing.</p>
            <p>Comments are strings, delimited by the symbols <code nobreak="false">(:</code> and <code nobreak="false">:)</code>. Comments may be nested.</p>
            <p>A comment may be used anywhere <termref def="IgnorableWhitespace">ignorable whitespace</termref> is allowed (see <specref ref="DefaultWhitespaceHandling"/>).</p>
            <p>The following is an example of a comment:</p>
            <eg xml:space="preserve">(: Houston, we have a problem :)</eg>
         </div2>
         <div2 id="id-primary-expressions">
            <head>Primary Expressions</head>
            <p>
               <termdef id="dt-primary-expression" term="primary expression">
               A <term>primary expression</term> is an instance of the production
               <nt def="doc-xquery40-PrimaryExpr">PrimaryExpr<!--$spec = xquery40--></nt>. Primary expressions are the basic primitives of the
	 language. They include literals, variable references, context value references, <phrase role="xquery">constructors, </phrase> and function calls. 
               A primary expression may also be created by enclosing any expression in parentheses, 
               which is sometimes helpful in controlling the precedence of operators.</termdef>
               <phrase role="xquery">Node Constructors are described in <specref ref="id-constructors"/>.</phrase>Map and Array Constructors are described in <specref ref="id-maps"/> and <specref ref="id-arrays"/>.
<phrase role="xquery">String Constructors are described in <specref ref="id-string-constructors"/>.</phrase>
            </p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-PrimaryExpr">
                  <lhs>PrimaryExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Literal">Literal<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ContextValueRef">ContextValueRef<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-FunctionCall">FunctionCall<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrderedExpr">OrderedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-UnorderedExpr">UnorderedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-NodeConstructor">NodeConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-FunctionItemExpr">FunctionItemExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-MapConstructor">MapConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ArrayConstructor">ArrayConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-StringTemplate">StringTemplate<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-StringConstructor">StringConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-UnaryLookup">UnaryLookup<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-Literal">
                  <lhs>Literal</lhs>
                  <rhs>
                     <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-VarRef">
                  <lhs>VarRef</lhs>
                  <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-ParenthesizedExpr">
                  <lhs>ParenthesizedExpr</lhs>
                  <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-ContextValueRef">
                  <lhs>ContextValueRef</lhs>
                  <rhs>"."</rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-FunctionCall">
                  <lhs>FunctionCall</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-ArgumentList">ArgumentList<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                  </com>
                  <com>
                     <loc href="#parse-note-parens">gn: parens</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-OrderedExpr">
                  <lhs>OrderedExpr</lhs>
                  <rhs>"ordered"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-UnorderedExpr">
                  <lhs>UnorderedExpr</lhs>
                  <rhs>"unordered"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-EnclosedExpr">
                  <lhs>EnclosedExpr</lhs>
                  <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-NodeConstructor">
                  <lhs>NodeConstructor</lhs>
                  <rhs>
                     <nt def="prod-xquery40-DirectConstructor">DirectConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ComputedConstructor">ComputedConstructor<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-FunctionItemExpr">
                  <lhs>FunctionItemExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-NamedFunctionRef">NamedFunctionRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-InlineFunctionExpr">InlineFunctionExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-NamedFunctionRef">
                  <lhs>NamedFunctionRef</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "#"  <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-InlineFunctionExpr">
                  <lhs>InlineFunctionExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  ("function"  |  "fn")  <nt def="prod-xquery40-FunctionSignature">FunctionSignature<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-FunctionBody">FunctionBody<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-MapConstructor">
                  <lhs>MapConstructor</lhs>
                  <rhs>"map"?  "{"  (<nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$idref_lang_part = xquery40- --></nt> ** ",")  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-ArrayConstructor">
                  <lhs>ArrayConstructor</lhs>
                  <rhs>
                     <nt def="prod-xquery40-SquareArrayConstructor">SquareArrayConstructor<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CurlyArrayConstructor">CurlyArrayConstructor<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-StringTemplate">
                  <lhs>StringTemplate</lhs>
                  <rhs>"`"  (<nt def="prod-xquery40-StringTemplateFixedPart">StringTemplateFixedPart<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-StringTemplateVariablePart">StringTemplateVariablePart<!--$idref_lang_part = xquery40- --></nt>)*  "`"</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-StringConstructor">
                  <lhs>StringConstructor</lhs>
                  <rhs>"``["  <nt def="prod-xquery40-StringConstructorContent">StringConstructorContent<!--$idref_lang_part = xquery40- --></nt>  "]``"</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-PrimaryExpr-UnaryLookup">
                  <lhs>UnaryLookup</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Lookup">Lookup<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <div3 id="id-literals">
               <head>Literals</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-Literal">
                     <lhs>Literal</lhs>
                     <rhs>
                        <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-Literal-NumericLiteral">
                     <lhs>NumericLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BinaryIntegerLiteral">BinaryIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DecimalLiteral">DecimalLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DoubleLiteral">DoubleLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-Literal-StringLiteral">
                     <lhs>StringLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-Literal-QNameLiteral">
                     <lhs>QNameLiteral</lhs>
                     <rhs>"#"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>
                  <termdef id="dt-literal" term="literal">A <term>literal</term> is a direct syntactic representation of an
		atomic item.</termdef> XQuery 4.0 supports three kinds of literals: numeric literals,
		string literals, and QName literals.</p>
               <div4 id="id-numeric-literals">
                  <head>Numeric Literals</head>
                  <changes>
                     <change issue="429" PR="433" date="2023-04-25">
                     Numeric literals can now be written in hexadecimal or binary notation; 
                     and underscores can be included for readability.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-NumericLiteral">
                        <lhs>NumericLiteral</lhs>
                        <rhs>
                           <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BinaryIntegerLiteral">BinaryIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DecimalLiteral">DecimalLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DoubleLiteral">DoubleLiteral<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-IntegerLiteral">
                        <lhs>IntegerLiteral</lhs>
                        <rhs>
                           <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-Digits">
                        <lhs>Digits</lhs>
                        <rhs>
                           <nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>  |  "_")*  <nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-DecDigit">
                        <lhs>DecDigit</lhs>
                        <rhs>[0-9]</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-HexIntegerLiteral">
                        <lhs>HexIntegerLiteral</lhs>
                        <rhs>"0x"  <nt def="prod-xquery40-HexDigits">HexDigits<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-HexDigits">
                        <lhs>HexDigits</lhs>
                        <rhs>
                           <nt def="prod-xquery40-HexDigit">HexDigit<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-HexDigit">HexDigit<!--$idref_lang_part = xquery40- --></nt>  |  "_")*  <nt def="prod-xquery40-HexDigit">HexDigit<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-HexDigit">
                        <lhs>HexDigit</lhs>
                        <rhs>[0-9a-fA-F]</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-BinaryIntegerLiteral">
                        <lhs>BinaryIntegerLiteral</lhs>
                        <rhs>"0b"  <nt def="prod-xquery40-BinaryDigits">BinaryDigits<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-BinaryDigits">
                        <lhs>BinaryDigits</lhs>
                        <rhs>
                           <nt def="prod-xquery40-BinaryDigit">BinaryDigit<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-BinaryDigit">BinaryDigit<!--$idref_lang_part = xquery40- --></nt>  |  "_")*  <nt def="prod-xquery40-BinaryDigit">BinaryDigit<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-BinaryDigit">
                        <lhs>BinaryDigit</lhs>
                        <rhs>[01]</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-DecimalLiteral">
                        <lhs>DecimalLiteral</lhs>
                        <rhs>("."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>)  |  (<nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>  "."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NumericLiteral-DoubleLiteral">
                        <lhs>DoubleLiteral</lhs>
                        <rhs>(("."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>)  |  (<nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>  ("."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>?)?))  [eE]  [+-]?  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>
                  </scrap>
                  <p diff="add" at="2023-04-07">The value of a numeric literal is determined as follows (taking the rules in order):</p>
                  <olist diff="chg" at="2023-04-07">
                     <item>
                        <p>Underscore characters are stripped out. Underscores may be included in a numeric
                  literal to aid readability, but have no effect on the value. For example, <code nobreak="false">1_000_000</code>
                  is equivalent to <code nobreak="false">1000000</code>.</p>
                        <note>
                           <p diff="add" at="2023-04-25">Underscores must not appear at the beginning or end of a sequence of digits, only
                  in intermediate positions. Multiple adjacent underscores are allowed.</p>
                        </note>
                     </item>
                     <item>
                        <p>A <code nobreak="false">HexIntegerLiteral</code> represents a non-negative integer
                      expressed in hexadecimal: for example <code nobreak="false">0xffff</code> represents the integer 65535, and
                     <code nobreak="false">0xFFFF_FFFF</code> represents the integer 4294967295.</p>
                     </item>
                     <item>
                        <p>A <code nobreak="false">BinaryIntegerLiteral</code> represents a non-negative integer
                     expressed in binary: for example <code nobreak="false">0b101</code> represents the integer 5, and
                     <code nobreak="false">0b1111_1111</code> represents the integer 255.</p>
                     </item>
                     <item>
                        <p>The value of a <term>numeric literal</term> containing no <code nobreak="false">.</code> and 
                     no <code nobreak="false">e</code> or <code nobreak="false">E</code> character is an atomic item of type <code nobreak="false">xs:integer</code>;
                     the value is obtained by casting from <code nobreak="false">xs:string</code> to <code nobreak="false">xs:integer</code> as specified in
                     <xspecref spec="FO40" ref="casting-from-strings"/>.</p>
                     </item>
                     <item>
                        <p>The value of a numeric literal containing <code nobreak="false">.</code> but no <code nobreak="false">e</code> or <code nobreak="false">E</code> 
                     character is an atomic item of type <code nobreak="false">xs:decimal</code>;
                     the value is obtained by casting from <code nobreak="false">xs:string</code> to <code nobreak="false">xs:decimal</code> as specified in
                     <xspecref spec="FO40" ref="casting-from-strings"/>.</p>
                     </item>
                     <item>
                        <p>The value of a numeric literal 
                     containing an <code nobreak="false">e</code> or <code nobreak="false">E</code> character is an atomic item of type 
                     <code nobreak="false">xs:double</code>;
                     the value is obtained by casting from <code nobreak="false">xs:string</code> to <code nobreak="false">xs:double</code> as specified in
                     <xspecref spec="FO40" ref="casting-from-strings"/>.</p>
                     </item>
                  </olist>
                  <note diff="add" at="2023-04-07">
                     <p>The value of a numeric literal is always non-negative. An expression may
                  appear to include a negative number such as <code nobreak="false">-1</code>, but this is technically
                  an arithmetic expression comprising a unary minus operator followed by a numeric literal.</p>
                  </note>
                  <note>
                     <p>The effect of the above rules is that in the case of an integer or decimal literal, a dynamic error <xerrorref spec="FO40" class="AR" code="0002"/> will generally be raised if the literal is outside the range of values supported by the implementation (other options are available: see <xspecref spec="FO40" ref="op.numeric"/> for details.)</p>
                     <p role="xquery">The limits of numeric datatypes are specified in <specref ref="id-data-model-conformance"/>.</p>
                  </note>
                  <p>Here are some examples of numeric literals:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">12</code> denotes the <code nobreak="false">xs:integer</code> value twelve.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">1_000_000</code> denotes the <code nobreak="false">xs:integer</code> value one million.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">12.5</code> denotes the <code nobreak="false">xs:decimal</code> value twelve and one half.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">3.14159_26535_89793e0</code>
                  is an <code nobreak="false">xs:double</code> value representing the mathematical constant
                  <var>π</var> to 15 decimal places. </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">125E2</code> denotes the <code nobreak="false">xs:double</code> value twelve thousand, five hundred.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">0xffff</code> denotes the <code nobreak="false">xs:integer</code> value 65535.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">0b1000_0001</code> denotes the <code nobreak="false">xs:integer</code> value 129.</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-string-literal">
                  <head>String Literals</head>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-StringLiteral">
                        <lhs>StringLiteral</lhs>
                        <rhs>
                           <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-StringLiteral-AposStringLiteral">
                        <lhs>AposStringLiteral</lhs>
                        <rhs>"'"  (<nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EscapeApos">EscapeApos<!--$idref_lang_part = xquery40- --></nt>  |  [^'&amp;])*  "'"</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-StringLiteral-PredefinedEntityRef">
                        <lhs>PredefinedEntityRef</lhs>
                        <rhs>"&amp;"  ("lt"  |  "gt"  |  "amp"  |  "quot"  |  "apos")  ";"</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-StringLiteral-CharRef">
                        <lhs>CharRef</lhs>
                        <rhs>
                           <xnt ref="NT-CharRef" spec="XML">[http://www.w3.org/TR/REC-xml#NT-CharRef]</xnt>
                        </rhs>
                        <com>
                           <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-StringLiteral-EscapeApos">
                        <lhs>EscapeApos</lhs>
                        <rhs>"''"</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-StringLiteral-QuotStringLiteral">
                        <lhs>QuotStringLiteral</lhs>
                        <rhs>'"'  (<nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EscapeQuot">EscapeQuot<!--$idref_lang_part = xquery40- --></nt>  |  [^"&amp;])*  '"'</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-StringLiteral-EscapeQuot">
                        <lhs>EscapeQuot</lhs>
                        <rhs>'""'</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>
                  </scrap>
                  <p>The value of a <term>string literal</term> is an atomic item whose type is
               <code nobreak="false">xs:string</code> and whose value is the string denoted by the characters between the
		delimiting apostrophes or quotation marks. If the literal is delimited by apostrophes, two adjacent 
		apostrophes within the literal are interpreted as a single apostrophe. Similarly, if the literal 
		is delimited by quotation marks, two adjacent quotation marks within the literal are interpreted 
		as one quotation mark.</p>
                  <p role="xquery">
                     <termdef term="predefined entity reference" id="dt-predefined-entity-reference">A <term>predefined entity reference</term> is a short sequence of characters, 
                  beginning with an ampersand, that represents a single character that might otherwise 
                  have syntactic significance.</termdef> Each predefined entity reference is replaced 
                  by the character it represents when the string literal is processed. The predefined 
                  entity references recognized by XPath and XQuery are as follows:</p>
                  <p role="xquery">
                     <table width="60%" border="1" role="medium">
                        <tbody>
                           <tr>
                              <th align="center" rowspan="1" colspan="1">Entity Reference</th>
                              <th align="center" rowspan="1" colspan="1">Character Represented</th>
                           </tr>
                           <tr>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&amp;lt;</code>
                              </td>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&lt;</code>
                              </td>
                           </tr>
                           <tr>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&amp;gt;</code>
                              </td>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&gt;</code>
                              </td>
                           </tr>
                           <tr>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&amp;amp;</code>
                              </td>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&amp;</code>
                              </td>
                           </tr>
                           <tr>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&amp;quot;</code>
                              </td>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">"</code>
                              </td>
                           </tr>
                           <tr>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">&amp;apos;</code>
                              </td>
                              <td align="center" rowspan="1" colspan="1">
                                 <code nobreak="false">'</code>
                              </td>
                           </tr>
                        </tbody>
                     </table>
                  </p>
                  <p role="xquery">
                     <termdef term="character reference" id="dt-character-reference">A <term>character reference</term> is an XML-style reference to a <bibref ref="Unicode"/> character, identified by its decimal or hexadecimal codepoint.</termdef> For example, 
                  the character <char>U+20AC</char> 
               can be represented by the character reference <code nobreak="false">&amp;#8364;</code> or <code nobreak="false">&amp;#x20ac;</code>. Character references are 
               normatively defined in Section 4.1 of the XML specification (it is <termref def="dt-implementation-defined">implementation-defined</termref> whether the rules in <bibref ref="XML"/> or <bibref ref="XML1.1"/> apply.) A <termref def="dt-static-error">static error</termref>
                     <errorref class="ST" code="0090"/> is raised if a character reference does not identify a valid character in the version of XML that is in use.</p>
                  <p>Here are some examples of string literals:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">"He said, ""I don't like it."""</code> denotes a string containing two quotation marks and one apostrophe.</p>
                     </item>
                     <item role="xquery">
                        <p>
                           <code role="parse-test" nobreak="false">"Ben &amp;amp; Jerry&amp;apos;s"</code> denotes the <code nobreak="false">xs:string</code> value  <code nobreak="false">"Ben &amp; Jerry's"</code>.</p>
                     </item>
                     <item role="xquery">
                        <p>
                           <code role="parse-test" nobreak="false">"&amp;#8364;99.50"</code> denotes the <code nobreak="false">xs:string</code>  value <code nobreak="false">"€99.50"</code>.</p>
                     </item>
                     <item>
                        <p>In XQuery, the string literal <code nobreak="false">"&amp;lt;"</code> denotes a string of length 1 containing the single character
                     <code nobreak="false">"&lt;"</code>. In XPath, the string literal <code nobreak="false">"&amp;lt;"</code> denotes a string of length 4 containing the four 
                     characters <code nobreak="false">"&amp;"</code>, <code nobreak="false">"l"</code>, <code nobreak="false">"t"</code>, <code nobreak="false">";"</code>. (However, when the XPath
                     expression is embedded in an XML document, the sequence <code nobreak="false">"&amp;lt;"</code> will typically have already been converted
                     to <code nobreak="false">"&lt;"</code> by the XML parser.)</p>
                     </item>
                  </ulist>
                  <note>
                     <p>When XPath or XQuery expressions are embedded in contexts where quotation
                     marks have special significance, such as inside XML attributes, or in string literals in a host language such
                     as Java or C#, then additional
                     escaping may be needed.</p>
                  </note>
                  <note>
                     <p>Fixed string values can also be written as string templates: 
                  see <specref ref="id-string-templates"/>. A string template with no enclosed
               expressions, such as <code nobreak="false">`Jamaica`</code> evaluates to the same value as
               the string literals <code nobreak="false">"Jamaica"</code> or <code nobreak="false">'Jamaica'</code>. 
               A string template can contain both single and double quotation marks:
               <code nobreak="false">`He said: "I don't like it"`</code>. However, there there are
               some subtle differences:</p>
                     <ulist>
                        <item>
                           <p>In string literals, the treatment of character and entity references
                  such as <code nobreak="false">&amp;amp;</code> varies between XQuery and XPath; in string templates,
                  such references are not expanded in either language.</p>
                        </item>
                        <item>
                           <p>String templates can only be used where an expression is expected. String
                  literals are also used in some non-expression contexts, for example in
                  defining an enumeration type: see <specref ref="id-enumeration-types"/>.</p>
                        </item>
                        <item>
                           <p>Curly brackets (<char>U+007B</char> and <char>U+007D</char>) and backticks 
                  (<char>U+0060</char>) have a reserved meaning in string templates.</p>
                        </item>
                     </ulist>
                  </note>
               </div4>
               <div4 id="id-qname-literals">
                  <head>QName Literals</head>
                  <changes>
                     <change issue="1661">QName literals are new in 4.0.</change>
                  </changes>
                  <p>A QName literal represents a value of type <code nobreak="false">xs:QName</code>.</p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-QNameLiteral">
                        <lhs>QNameLiteral</lhs>
                        <rhs>"#"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-QNameLiteral-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>
                  </scrap>
                  <p>For example, the expression <code nobreak="false">node-name($node) = #xml:space</code>
               returns true if the name of the node <code nobreak="false">$node</code> is the QName with local part <code nobreak="false">space</code>
                  and namespace URI <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.</p>
                  <p>If the <code nobreak="false">EQName</code> is an unprefixed <code nobreak="false">NCName</code>, then it is expanded using
                  the <termref def="dt-no-namespace-rule"/>. If there
                  is no binding for the prefix in the <termref def="dt-static-namespaces"/> then
                  a static error is raised <errorref class="ST" code="0081"/>.
               </p>
                  <note>
                     <p>No whitespace or comment is permitted between the <code nobreak="false">#</code> character
                  and the <code nobreak="false">EQName</code>.</p>
                     <p>In XQuery, the character pair <code nobreak="false">(#</code> is recognized as the start of
                     a pragma. In order to ensure that an expression such as <code nobreak="false">error(#err:XPTY0004)</code>
                     is correctly parsed, the rules for pragmas have changed to require whitespace
                     after the opening <code nobreak="false">(#</code> and before the <code nobreak="false">EQName</code>.</p>
                  </note>
                  <note>
                     <p>A <code nobreak="false">QNameLiteral</code> is an expression that evaluates to a single
                  item of type <code nobreak="false">xs:QName</code>; it is thus an alternative to calling the
                  <code nobreak="false">xs:QName</code> constructor function with a literal string argument.
                  This should not be confused with QNames that are used directly in XQuery 4.0 to refer to constructs such as
               functions, variables, and elements.</p>
                     <p>A <code nobreak="false">QName</code> appearing on its own as an expression,
               for example <code nobreak="false">my:invoice</code>, is an abbreviation for the axis step <code nobreak="false">child::my:step</code>,
               which selects a child element of the context node having this particular element name. A different
               construct is therefore needed to represent an atomic item of type <code nobreak="false">xs:QName</code>.
               For example, the function <code nobreak="false">fn:error</code> expects an <code nobreak="false">xs:QName</code> value
               as its first argument, so (provided that the prefix <code nobreak="false">err</code> is defined in the static
               context) it is possible to use a call such as <code nobreak="false">error( #err:XPTY0004 )</code> to raise an
               error with this error code.</p>
                  </note>
               </div4>
               <div4 id="id-constants-other-types">
                  <head>Constants of Other Types</head>
                  <p>
               
      The <code nobreak="false">xs:boolean</code> values <code nobreak="false">true</code> and <code nobreak="false">false</code> can be constructed by calls to the
      <termref def="dt-system-function">system functions</termref>
                     <code nobreak="false">fn:true()</code> and <code nobreak="false">fn:false()</code>, respectively.
    </p>
                  <p>Values of other simple types can be constructed by calling the <termref def="dt-constructor-function">constructor function</termref> for the given type. The constructor functions for XML Schema
		built-in types are defined in <xspecref spec="FO40" ref="constructor-functions-for-xsd-types"/>. In general, the name of a constructor function for a given type is the same as the name of the type (including its namespace). For
		example:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">xs:integer("12")</code> returns the integer value twelve.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">xs:date("2001-08-25")</code> returns an item whose type is <code nobreak="false">xs:date</code> and whose value represents the date 25th August 2001.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">xs:dayTimeDuration("PT5H")</code> returns an item whose type is <code nobreak="false">xs:dayTimeDuration</code> and whose value represents a duration of five hours.</p>
                     </item>
                  </ulist>
                  <p>Constructor functions can also be used to create special values that have no literal representation, as in the following examples:
<ulist>
                        <item>
                           <p>
                              <code role="parse-test" nobreak="false">xs:float("NaN")</code> returns the special floating-point value, "Not a Number."</p>
                        </item>
                        <item>
                           <p>
                              <code role="parse-test" nobreak="false">xs:double("INF")</code> returns the special double-precision value, "positive infinity."</p>
                        </item>
                     </ulist>
                  </p>
                  <p>Constructor functions are available for all simple types,
including union types. For example, if <code nobreak="false">my:dt</code> is a user-defined union
type whose member types are <code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>, and <code nobreak="false">xs:dateTime</code>, then
the expression <code nobreak="false">my:dt("2011-01-10")</code> creates an atomic item of type
<code nobreak="false">xs:date</code>. The rules follow XML Schema validation rules for union types:
the effect is to choose the first member type that accepts the given
string in its lexical space.</p>
                  <p>It is also possible to construct values of various types by using a <code nobreak="false">cast</code> expression. For example:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">9 cast as
                        hatsize</code> returns the atomic item <code nobreak="false">9</code>
			 whose type is  <code nobreak="false">hatsize</code>.</p>
                     </item>
                  </ulist>
               </div4>
            </div3>
            <div3 id="id-variables">
               <head>Variable References</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-VarRef">
                     <lhs>VarRef</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-VarRef-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>
                  <termdef id="dt-variable-reference" term="variable reference">A <term>variable reference</term> is an EQName preceded by a $-sign.</termdef>
                The variable name is expanded using the <termref def="dt-no-namespace-rule"/>.
                Two variable references are equivalent if their  <termref def="dt-expanded-qname">expanded QNames</termref>  are equal (as defined by the <code nobreak="false">eq</code> operator). The scope of a variable binding is defined separately for each kind of
expression that can bind variables.</p>
               <p>Every variable reference must match a name in the <termref def="dt-in-scope-variables">in-scope variables</termref>. </p>
               <p>Every variable binding has a static scope. The scope defines where
references to the variable can validly occur.

It is a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0008"/> to reference a variable that is not in scope. If a variable is bound in the <termref def="dt-static-context">static context</termref> for an expression, that variable is in scope for the entire expression except where it is occluded by another binding that uses the same name within that scope.</p>
               <p role="xquery">A reference to a variable that was declared <code nobreak="false">external</code>, but was not bound to a value by the external environment, raises a <termref def="dt-dynamic-error">dynamic error</termref>
                  <errorref code="0002" class="DY"/>.</p>
               <p>
At evaluation time, the value of a variable reference is the value to which the relevant variable is bound.</p>
               <!--<p diff="add" at="A">A <code>VarRef</code> consisting of a $-sign followed by an integer literal is refered to as a
            <term>numeric parameter reference</term>, and is allowed only within an inline function declared using hash notation:
            see <specref ref="id-hash-inline-functions"/></p>-->
            </div3>
            <div3 id="id-context-value-references">
               <head>Context Value References</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-ContextValueRef">
                     <lhs>ContextValueRef</lhs>
                     <rhs>"."</rhs>
                  </prod>
               </scrap>
               <p>A <term>context value reference</term> evaluates to
              the <termref def="dt-context-value"/>.</p>
               <p>In many syntactic contexts, the context value will be a single item.
               For example this applies on the right-hand side of the <code nobreak="false">/</code> 
               or <code nobreak="false">!</code> operators, or within a <nt def="doc-xquery40-Predicate">Predicate<!--$spec = xquery40--></nt>.</p>
               <p>If the <termref def="dt-context-value"/> is <xtermref spec="DM40" ref="dt-absent"/>, a context value reference raises a <termref def="dt-type-error"/>
                  <errorref class="DY" code="0002"/>.</p>
               <note>
                  <p>Being absent is not the same thing as being empty.</p>
               </note>
            </div3>
            <div3 id="id-paren-expressions">
               <head>Parenthesized Expressions</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-ParenthesizedExpr">
                     <lhs>ParenthesizedExpr</lhs>
                     <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-ParenthesizedExpr-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>
               </scrap>
               <p>Parentheses may be used to override the precedence rules.
        For example, the expression <code role="parse-test" nobreak="false">(2 + 4)
		    * 5</code> evaluates to thirty, since the parenthesized expression <code role="parse-test" nobreak="false">(2 + 4)</code> is evaluated first and its result is multiplied by five. Without
			 parentheses, the expression <code role="parse-test" nobreak="false">2 + 4 * 5</code> evaluates to twenty-two, because the multiplication operator has higher
			 precedence than the addition operator.</p>
               <p>Empty parentheses are used to denote the empty sequence, as
		described in <specref ref="construct_seq"/>.</p>
            </div3>
            <div3 id="id-enclosed-expr">
               <head>Enclosed Expressions</head>
               <p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>

                     <prod id="doc-xquery40-EnclosedExpr-Expr">
                        <lhs>Expr</lhs>
                        <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                     </prod>
                  </scrap>
                  <termdef term="enclosed expression" id="dt-enclosed-expression">An <term>enclosed expression</term> is an instance of the <nt def="doc-xquery40-EnclosedExpr">EnclosedExpr<!--$spec = xquery40--></nt> production, which allows an optional expression within curly brackets.</termdef>
                  <termdef id="dt-content-expression" term="content expression">In an  <termref def="dt-enclosed-expression">enclosed expression</termref>, the optional expression enclosed in curly brackets is called the <term>content expression</term>.</termdef> If the <termref def="dt-content-expression">content expression</termref> is not provided explicitly,  the content expression is <code nobreak="false">()</code>.</p>
               <note diff="add" at="A">
                  <p>Despite the name, an enclosed expression is not actually an expression
                  in its own right; rather it is a construct that is used in the grammar of many other expressions.</p>
               </note>
            </div3>
         </div2>
         <div2 id="id-postfix-expression">
            <head>Postfix Expressions</head>
            <scrap headstyle="show">
               <head/>
               <prod id="doc-xquery40-PostfixExpr">
                  <lhs>PostfixExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PostfixExpr-PrimaryExpr">
                  <lhs>PrimaryExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Literal">Literal<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ContextValueRef">ContextValueRef<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-FunctionCall">FunctionCall<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrderedExpr">OrderedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-UnorderedExpr">UnorderedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-NodeConstructor">NodeConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-FunctionItemExpr">FunctionItemExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-MapConstructor">MapConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ArrayConstructor">ArrayConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-StringTemplate">StringTemplate<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-StringConstructor">StringConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-UnaryLookup">UnaryLookup<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PostfixExpr-FilterExpr">
                  <lhs>FilterExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-Predicate">Predicate<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PostfixExpr-DynamicFunctionCall">
                  <lhs>DynamicFunctionCall</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PostfixExpr-LookupExpr">
                  <lhs>LookupExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-Lookup">Lookup<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PostfixExpr-MethodCall">
                  <lhs>MethodCall</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  "=?&gt;"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-PostfixExpr-FilterExprAM">
                  <lhs>FilterExprAM</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  "?["  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "]"</rhs>
               </prod>
            </scrap>
            <p>A postfix expression takes one of the following forms:</p>
            <ulist>
               <item>
                  <p>
                     <termdef term="filter expression" id="dt-filter-expression">
               A <term>filter expression</term> is an
               instance of the construct <nt def="doc-xquery40-FilterExpr">FilterExpr<!--$spec = xquery40--></nt>:
               that is, it is an expression in the form <code nobreak="false">
                           <var>E1</var>[<var>E2</var>]</code>. 
               Its effect is to return those items from the value of <var>E1</var> that
               satisfy the predicate in <var>E2</var>.</termdef>
                  </p>
                  <p>Filter expressions are described in <specref ref="id-filter-expression"/>.</p>
                  <p>An example of a filter expression is <code nobreak="false">(1 to 100)[. mod 2 = 0]</code>
            which returns all even numbers in the range 1 to 100.</p>
                  <p>The base expression <var>E1</var> can itself be a postfix expression,
            so multiple predicates are allowed, in the form <code nobreak="false">
                        <var>E1</var>[<var>E2</var>][<var>E3</var>][<var>E4</var>]</code>.</p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-dynamic-function-call" term="dynamic function call">A <term>dynamic function call</term>
               is an instance of the construct <nt def="doc-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$spec = xquery40--></nt>:
               that is, it is an expression in the form <code nobreak="false">
                           <var>E1</var>(<var>E2</var>, <var>E3</var>, ...)</code>
               in which <var>E1</var> identifies a <termref def="dt-function-item"/>
               to be called, and the parenthesized argument list
                <code nobreak="false">(<var>E2</var>, <var>E3</var>, ...)</code>) identifies the arguments supplied to the function.</termdef> Its
               effect is to evaluate <var>E1</var> to obtain a function,
               and then call that function, with the values of expressions
               <var>E2</var>, <var>E3</var>, <code nobreak="false">...</code> as
               arguments. Dynamic function calls are described in <specref ref="id-dynamic-function-invocation"/>.</p>
                  <p>An example of a dynamic function call is <code nobreak="false">$f("a", 2)</code> where
            the value of variable <code nobreak="false">$f</code> must be a function item.</p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-lookup-expression" term="lookup expression">
               A <term>lookup expression</term> is an instance of the production
                  <nt def="doc-xquery40-LookupExpr">LookupExpr<!--$spec = xquery40--></nt>: that is, an expression in the form
                  <code nobreak="false">
                           <var>E1</var>?<var>KS</var>
                        </code>, where <var>E1</var> is an expression returning a sequence
            of maps or arrays, and <var>KS</var> is a key specifier, which indicates which
            entries in a map, or members in an array, should be selected.</termdef>
                  </p>
                  <p>Lookup expressions are described in <specref ref="id-postfix-lookup"/>.</p>
                  <p>An example of a lookup expression is <code nobreak="false">$emp?name</code>, where
            the value of variable <code nobreak="false">$emp</code> is a map, and the string <code nobreak="false">"name"</code>
            is the key of one of the entries in the map.</p>
               </item>
               <item>
                  <p>
                     <termdef term="filter expression for maps and arrays"
                              id="dt-filter-expression-ma">
               A <term>filter expression for maps and arrays</term> is an
               instance of the construct <nt def="doc-xquery40-FilterExprAM">FilterExprAM<!--$spec = xquery40--></nt>:
               that is, it is an expression in the form <code nobreak="false">
                           <var>E1</var>?[<var>E2</var>]</code>. 
               Its effect is to evaluate <var>E1</var> to return an array or map, and to select
               members of the array, or entries from the map, that satisfy the predicate in <var>E2</var>.</termdef>
                  </p>
                  <p>Filter expressions for maps and array are described in <specref ref="id-filter-maps-and-arrays"/>.</p>
               </item>
            </ulist>
            <p>Postfix expressions are evaluated from left-to-right. For example, the 
         expression <code nobreak="false">$E1[E2]?(E3)(E4)</code> is evaluated by first evaluating
            the filter expression <code nobreak="false">$E1[E2]</code> to produce a sequence of maps and arrays 
            (say <code nobreak="false">$S</code>), then evaluating the lookup expression <code nobreak="false">$S?(E3)</code>
            to produce a function item (say <code nobreak="false">$F</code>), then evaluating the dynamic
            function call <code nobreak="false">$F(E4)</code> to produce the final result.</p>
            <note>
               <p>The grammar for postfix expressions is defined here in a way designed
         to link clearly to the semantics of the different kinds of expression. For parsing
         purposes, the equivalent production rule:</p>
               <eg xml:space="preserve">PostfixExpr := PrimaryExpr (Predicate | PositionalArgumentList | Lookup)*</eg>
               <p>(as used in XPath 3.1) is probably more convenient.</p>
            </note>
         </div2>
         <div2 id="id-filter-expression">
            <head>Filter Expressions</head>
            <changes>
               <change issue="816" PR="996" date="2024-02-06">
                  The value of a predicate in a filter expression can now be a sequence of integers.
               </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-FilterExpr">
                  <lhs>FilterExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-Predicate">Predicate<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FilterExpr-PostfixExpr">
                  <lhs>PostfixExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FilterExpr-Predicate">
                  <lhs>Predicate</lhs>
                  <rhs>"["  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "]"</rhs>
               </prod>
            </scrap>
            <p>A <termref def="dt-filter-expression"/> consists of a base expression followed by
               a predicate, which is an expression written in square
               brackets. The result of the filter expression consists of the
               items returned by the base expression, filtered by applying the
               predicate to each item in turn. The ordering of the items
               returned by a filter expression is the same as their order in
               the result of the primary expression.</p>
            <note>
               <p>Where the expression before the square brackets is an
                  <nt def="doc-xquery40-AbbreviatedStep">AbbreviatedStep<!--$spec = xquery40--></nt> or <nt def="prod-xquery40-FullStep">FullStep<!--$spec = xquery40--></nt>, the expression is technically not a
                  filter expression but an <nt def="doc-xquery40-AxisStep">AxisStep<!--$spec = xquery40--></nt>. There are minor differences
                  in the semantics: see <specref ref="id-predicate"/>
               </p>
            </note>
            <p>Here are some examples of filter expressions:</p>
            <ulist>
               <item>
                  <p>Given a sequence of products in a variable, return only those products whose price is greater than 100.</p>
                  <eg role="parse-test" xml:space="preserve">$products[price gt 100]</eg>
               </item>
               <item>
                  <p>List all the integers from 1 to 100 that are divisible by 5. (See <specref ref="construct_seq"/> for an explanation of the <code nobreak="false">to</code> operator.)</p>
                  <eg role="parse-test" xml:space="preserve">(1 to 100)[. mod 5 eq 0]</eg>
               </item>
               <item>
                  <p>The result of the following expression is the integer 25:</p>
                  <eg role="parse-test" xml:space="preserve">(21 to 29)[5]</eg>
               </item>
               <item>
                  <p>The following example returns the fifth through ninth items in the sequence bound to variable <code nobreak="false">$orders</code>.</p>
                  <eg role="parse-test" diff="chg" at="issue816" xml:space="preserve">$orders[5 to 9]</eg>
               </item>
               <item>
                  <p>The following example illustrates the use of a filter expression as a <termref def="dt-step">step</termref> in a <termref def="dt-path-expression">path expression</termref>. It returns the last chapter or appendix within the book bound to variable <code nobreak="false">$book</code>:</p>
                  <eg role="parse-test" xml:space="preserve">$book/(chapter | appendix)[last()]</eg>
               </item>
            </ulist>
            <p>For each item in the input sequence, the predicate expression
               is evaluated using an <term>inner focus</term>, defined as
               follows: The context value is the item currently being tested
               against the predicate. The context size is the number of items
               in the input sequence. The context position is the position of
               the context value within the input sequence. </p>
            <p>For each item in the input sequence, the result of the
               predicate expression is coerced to an <code nobreak="false">xs:boolean</code>
               value, called the <termref def="dt-predicate-truth-value"/>, as
               described below. Those items for which the predicate truth value
               is <code nobreak="false">true</code> are retained, and those for which the
               predicate truth value is <code nobreak="false">false</code> are discarded.</p>
            <p>
               <termdef id="dt-predicate-truth-value" term="predicate truth value">The
            <term>predicate truth value</term> of a value <code nobreak="false">$V</code>
            is the result of the expression <code nobreak="false">if ($V instance of xs:numeric+)
            then ($V = position()) else fn:boolean($V)</code>.</termdef>
            </p>
            <p>Expanding this definition, the predicate truth value can be obtained 
               by applying the following rules, in order:</p>
            <olist>
               <item diff="chg" at="issue816">
                  <p>If the value <var>V</var> of the predicate expression 
                     is a sequence whose first item is an instance of the type <code nobreak="false">xs:numeric</code>,
                     then:</p>
                  <olist>
                     <item>
                        <p>
                           <var>V</var> must be an instance of the type
                        <code nobreak="false">xs:numeric+</code> (that is, every item in <var>V</var>
                           must be numeric). A type error <xerrorref spec="FO40" class="RG" code="0006"/> is
                        raised if this is not the case.</p>
                     </item>
                     <item>
                        <p>The predicate truth value is <code nobreak="false">true</code> if 
                           <var>V</var> is equal (by the
                           <code nobreak="false">=</code> operator) to the <term>context
                              position</term>, and is <code nobreak="false">false</code>
                           otherwise.</p>
                     </item>
                  </olist>
                  <p>In effect this means that an item in the input sequence is selected
                  if its position in the sequence is equal to one or more of the numeric
                  values in the predicate. For example, the predicate <code nobreak="false">[3 to 5]</code>
                  is true for the third, fourth, and fifth items in the input sequence.</p>
                  <p>
                     <termdef term="numeric predicate" role="xquery" id="dt-numeric-predicate">A predicate whose predicate
                     expression returns a value of type <code nobreak="false">xs:numeric+</code> is called a <term>numeric
                        predicate</term>.</termdef>
                  </p>
                  <note>
                     <p>It is possible, though not generally useful, for the value of a numeric
                  predicate to depend on the focus, and thus to differ for different items
                  in the input sequence. For example, the predicate <code nobreak="false">[xs:integer(@seq)]</code>
                  selects those items in the input sequence whose <code nobreak="false">@seq</code> attribute
                  is numerically equal to their position in the input sequence.</p>
                     <p>It is also possible, and again not generally useful, for the value of the predicate
                  to be numeric for some items in the input sequence, and boolean for others.
                  For example, the predicate <code nobreak="false">[@special otherwise last()]</code>
                  is true for an item that either has an <code nobreak="false">@special</code> attribute,
                     or is the last item in the input sequence.</p>
                  </note>
                  <note>
                     <p>The truth value of a numeric predicate does not depend on the order
                  of the numbers in <var>V</var>. The predicates <code nobreak="false">[ 1, 2, 3 ]</code>
                  and <code nobreak="false">[ 3, 2, 1 ]</code> have exactly the same effect. The items in 
                  the result of a filter expression always retain the ordering of the input
                  sequence.</p>
                  </note>
                  <note>
                     <p>The truth value of a numeric predicate whose value is non-integral
                  or non-positive is always false.</p>
                  </note>
                  <note>
                     <p>Beware that using boolean operators (<code nobreak="false">and</code>, <code nobreak="false">or</code>,
                  <code nobreak="false">not()</code>) with numeric values may not have the intended effect.
                  For example the predicate <code nobreak="false">[1 or last()]</code> selects every item
                  in the sequence, because <code nobreak="false">or</code> operates on the <termref def="dt-ebv"/>
                  of its operands. The required effect can be achieved with the predicate
                  <code nobreak="false">[1, last()]</code>.</p>
                  </note>
               </item>
               <item>
                  <p>Otherwise, the predicate truth value is the <termref def="dt-ebv">effective boolean value</termref> of the
                     predicate expression.</p>
               </item>
            </olist>
         </div2>
         <div2 id="id-functions">
            <head>Functions</head>
            <p diff="chg" at="B">Functions in XQuery 4.0 arise in two ways:</p>
            <ulist diff="chg" at="B">
               <item>
                  <p>A <termref def="dt-function-definition"/> contains information
               about a family of functions with the same name and a defined arity range. These functions
               are in most cases known statically (they appear in the <termref def="dt-statically-known-function-definitions"/>), 
               but there may be further function definitions
               that are known only dynamically (appearing in the <termref def="dt-dynamically-known-function-definitions"/>).</p>
               </item>
               <item>
                  <p>
                     <termref def="dt-function-item">Function items</termref> are XDM items that can be called
               using a <termref def="dt-dynamic-function-call"/>. They  are values that can be bound to variables, passed as
            arguments, returned as function results, and generally manipulated in the same way as other XDM values.</p>
               </item>
            </ulist>
            <p diff="chg" at="B">The functions defined by a statically known <termref def="dt-function-definition"/> can be invoked using a
            <termref def="dt-static-function-call"/>. <termref def="dt-function-item">Function items</termref> corresponding
            to these definitions can also be obtained, as dynamic values, by evaluating a <termref def="dt-named-function-ref"/>. 
            <termref def="dt-function-item">Function items</termref> can also be obtained using the <function>fn:function-lookup</function>
            function: in this case the function name and arity do not need to be known statically, and the function definition
            need not be present in the <termref def="dt-static-context"/>, so long as it is in the <termref def="dt-dynamic-context"/>.</p>
            <p>Static and dynamic function calls are described in the following sections.</p>
            <div3 id="id-static-functions" diff="add" at="A">
               <head>Static Function Calls</head>
               <p>The <termref def="dt-static-context"/> for an expression includes a set 
                  of <termref def="dt-statically-known-function-definitions"/>. Every <termref def="dt-function-definition"/>
               in the static context has a name (which is an <termref def="dt-expanded-qname"/>) and 
                  an <termref def="dt-arity-range"/>, which is a range of permitted arities for
               calls on that function. Two <termref def="dt-function-definition">function definitions</termref> 
                  having the same name must not have overlapping arity ranges.
               This means that for a given static function call, it is possible to identify the target function definition
               in the static context unambiguously from knowledge of the function name and the number of supplied arguments.</p>
               <p>A <termref def="dt-static-function-call"/> is bound to a <termref def="dt-function-definition"/> 
                  in the static context by matching the name
               and arity. If the function call has <var>P</var> positional arguments followed by
                  <var>K</var> keyword arguments, then the required arity is <var>P+K</var>, and the static context 
                  must include a <termref def="dt-function-definition"/> whose name matches the <termref def="dt-expanded-qname"/> 
                  in the function call, and whose <termref def="dt-arity-range"/> 
               includes this required arity. This is the function chosen to be called.
               The result of the function is obtained by evaluating the expression that forms its implementation, with
               a dynamic context that provides values for all the declared parameters, initialized
               as described in <specref ref="id-eval-static-function-call"/> below.</p>
               <p>Similarly, a <termref def="dt-named-function-ref"/> of the form <code nobreak="false">f#N</code> binds to a 
                  <termref def="dt-function-definition"/> in the
                  static context whose name matches <var>f</var> where <code nobreak="false">MinP ≤ N and MaxP ≥ N</code>.
               The result of evaluating a function reference is a <termref def="dt-function-item"/> which can be called
               using a dynamic function call. Function items are never variadic and their arguments
               are always supplied positionally. For example, the function reference <function>fn:concat#3</function>
               returns a function item with arity 3, which is always called by supplying three positional
               arguments, and whose effect is the same as a static call on <function>fn:concat</function> with
               three positional arguments. <!--The arity must not exceed the number of arguments that
               can be supplied positionally. Therefore, in the case of a function reference to a map-variadic functions
               such as <function>fn:serialize#2</function>, a dynamic call must supply the map-valued argument
               (the serialization parameters) in the form of a map; the function reference <function>fn:serialize#3</function>
               is an error, because <var>MaxP</var> = 2.--></p>
               <p>The detailed rules for evaluating static function calls and function references are defined
               in subsequent sections.</p>
               <div4 id="id-function-calls">
                  <head>Static Function Call Syntax</head>
                  <changes>
                     <change issue="155" PR="159" date="2020-09-30">
                  Keyword arguments are allowed on static function calls, as well as positional arguments.
               </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-FunctionCall">
                        <lhs>FunctionCall</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-ArgumentList">ArgumentList<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                        </com>
                        <com>
                           <loc href="#parse-note-parens">gn: parens</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-ArgumentList">
                        <lhs>ArgumentList</lhs>
                        <rhs>"("  ((<nt def="prod-xquery40-PositionalArguments">PositionalArguments<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-KeywordArguments">KeywordArguments<!--$idref_lang_part = xquery40- --></nt>)?)  |  <nt def="prod-xquery40-KeywordArguments">KeywordArguments<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-PositionalArguments">
                        <lhs>PositionalArguments</lhs>
                        <rhs>(<nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-Argument">
                        <lhs>Argument</lhs>
                        <rhs>
                           <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholder<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-ExprSingle">
                        <lhs>ExprSingle</lhs>
                        <rhs>
                           <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-ArgumentPlaceholder">
                        <lhs>ArgumentPlaceholder</lhs>
                        <rhs>"?"</rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-KeywordArguments">
                        <lhs>KeywordArguments</lhs>
                        <rhs>(<nt def="prod-xquery40-KeywordArgument">KeywordArgument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                     </prod>

                     <prod id="doc-xquery40-FunctionCall-KeywordArgument">
                        <lhs>KeywordArgument</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ":="  <nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>
                  </scrap>
                  <p>
                     <termdef term="static function call" id="dt-static-function-call">A <term>static function call</term>
               is an instance of the production <nt def="doc-xquery40-FunctionCall">FunctionCall<!--$spec = xquery40--></nt>: it
               consists of an EQName followed by a parenthesized list of zero or more arguments.</termdef>.</p>
                  <p>The EQName is expanded using the <termref def="dt-default-function-namespace-rule"/>.</p>
                  <p diff="add" at="A">The argument list consists of zero or more positional arguments,
               followed by zero or more keyword arguments.</p>
                  <p>
                     <termdef term="argument expression" id="dt-arg-expr">An argument to a function call is either an
               <term>argument expression</term> or an <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholder<!--$spec = xquery40--></nt> 
               (<code nobreak="false">?</code>); in both cases it may
            either be supplied positionally, or identified by a name (called a keyword).</termdef>
                  </p>
                  <p>This section is concerned with static function calls in which none of the arguments are
               <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholders<!--$spec = xquery40--></nt>. 
               Calls using one or more <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholders<!--$spec = xquery40--></nt> are covered in the 
               section <specref ref="id-partial-function-application"/>.</p>
                  <p>The <termref def="dt-expanded-qname">expanded QName</termref> used as the function name and the number of arguments used in the static function call 
               (the required arity) must match the name and arity range of a <termref def="dt-function-definition"/> 
               in the <termref def="dt-static-context">static context</termref>
                     <phrase> using the rules defined in the previous section</phrase>; if there is no match, a
               <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0017"/>.
               </p>
                  <p>Evaluation of static function calls is described in <specref ref="id-eval-static-function-call"/>
                     <phrase diff="del" at="B">,
               while evaluation of dynamic function calls is described in 
               <specref ref="id-eval-dynamic-function-call"/>
                     </phrase>.</p>
                  <p>Since the arguments of a function call are separated by commas, any <termref def="dt-arg-expr">argument expression</termref> that contains a top-level <termref def="dt-comma-operator">comma operator</termref> must be
               enclosed in parentheses. Here are some illustrative examples of
               static function calls:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">my:three-argument-function(1, 2, 3)</code> denotes a static function call with three 
                     <phrase diff="add" at="A">positional</phrase> arguments. <phrase diff="add" at="A">The 
                  corresponding function declaration must define at least three parameters, and may define
                  more, provided they are optional.</phrase>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">my:two-argument-function((1, 2), 3)</code> denotes a static function call with two arguments, the first of which is a
                     sequence of two values. <phrase diff="add" at="A">The 
                        corresponding function declaration must define at least two parameters, and may define
                        more, provided they are optional.</phrase>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">my:two-argument-function(1, ())</code> denotes a static function call with two arguments, 
                     the second of which is the empty sequence.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">my:one-argument-function((1, 2,
                        3))</code> denotes a static function call with one argument that is a sequence of three
                     values. </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">my:one-argument-function(( ))</code> denotes a static function call with one argument that is the empty sequence.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">my:zero-argument-function( )</code> denotes a static function call with zero arguments.</p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">lang(node := $n, language := 'de')</code> is a static function 
                     call with two keyword arguments. The corresponding function declaration defines two parameters,
                     a required parameter <code nobreak="false">language</code> and an optional parameter <code nobreak="false">node</code>.
                     This call supplies values for both parameters. It is equivalent to the call 
                     <code nobreak="false">fn:lang('de', $n)</code>. Note that the keyword arguments are in a different
                     order from the parameter declarations.
                  </p>
                     </item>
                     <item diff="add" at="A">
                        <p>
                           <code role="parse-test" nobreak="false">sort(//employee, key := fn($e) { xs:decimal($e/salary) })</code> is a static function 
                     call with one positional argument and one keyword argument. 
                     The corresponding function declaration defines three parameters,
                     a required parameter <code nobreak="false">$input</code>, an optional parameter <code nobreak="false">$collation</code>,
                     and an optional parameter <code nobreak="false">$key</code>
                     This call supplies values for the first and third parameters, leaving the second parameter (<code nobreak="false">$collation</code>)
                     to take its default value. The default value of the <code nobreak="false">$collation</code> parameter
                     is given as <code nobreak="false">fn:default-collation()</code>, so the value supplied to the function is the
                     default collation from the dynamic context of the caller. It is equivalent to the call 
                     <code nobreak="false">fn:sort(//employee, fn:default-collation(), fn($e) { xs:decimal($e/salary) })</code>.
                  </p>
                     </item>
                  </ulist>
                  <p>An <code nobreak="false">EQName</code> in a <code nobreak="false">KeywordArgument</code> is expanded 
               using the <termref def="dt-no-namespace-rule"/>.
            The keywords used in a function call (after expansion) must be distinct 
               <errorref class="ST" code="0017"/>.</p>
               </div4>
               <div4 id="id-eval-static-function-call" diff="chg" at="A">
                  <head>Evaluating Static Function Calls</head>
                  <p>This section applies to static function calls where none of the
            arguments is an <code nobreak="false">ArgumentPlaceholder</code>. For function calls involving
            placeholders, see <specref ref="id-partial-function-application"/>.</p>
                  <p>
                      When a static function call <var>FC</var> is evaluated
                      with respect to a static context <var>SC</var> and
                      a dynamic context <var>DC</var>,
                      the result is obtained as follows:
                    </p>
                  <olist>
                     <item>
                        <p>
                          The <termref def="dt-function-definition"/>
                           <var>FD</var> to be used is found in 
                        the <termref def="dt-statically-known-function-definitions"/> of <var>SC</var>.
                        </p>
                        <p>The <term>required arity</term> is the total number of arguments in the
                        function call, including both positional and keyword arguments.</p>
                        <p>
                              There can be at most one <termref def="dt-function-definition"/>
                           <var>FD</var> in the 
                              <termref def="dt-statically-known-function-definitions"/> component of <var>SC</var> whose function name
                              matches the <termref def="dt-expanded-qname"/> in <var>FC</var> and whose <termref def="dt-arity-range"/>
                              includes the arity of <var>FC</var>’s <code nobreak="false">ArgumentList</code>.
                           </p>
                        <p>If there is no such <termref def="dt-function-definition"/>, a static error <errorref class="ST" code="0017"/> is raised.</p>
                     </item>
                     <item>
                        <p>Each parameter in the <termref def="dt-function-definition"/>
                           <var>FD</var> is matched to an argument
                     expression as follows:</p>
                        <olist>
                           <item>
                              <p>If there are <var>N</var> positional arguments in the function call <var>FC</var>,
                           <!--and <var>FD</var> is not <termref def="dt-variadic"/>, -->then
                           the corresponding argument expressions are matched pairwise to the first <var>N</var>
                           parameters in the declaration. For this purpose the required parameters and optional parameters
                           in <var>FD</var> are concatenated into a single list, in order.</p>
                           </item>
                           <!--<item><p>If there are <var>N</var> positional arguments and no keyword arguments
                           in the function call <var>FC</var>,
                           and <var>FD</var> is <termref def="dt-variadic"/> with <var>M</var> declared
                           parameters, then:</p>
                           <olist>
                              <item><p>If <var>N</var> = <var>M-1</var>, then the <var>N</var>
                              supplied arguments are matched to the first <var>N</var> declared parameters,
                              and the <var>M</var>th parameter is bound to the empty sequence (which might cause
                              a type error if the declared type does not allow the empty sequence).</p></item>
                              <item><p>If <var>N</var> = <var>M</var>, then the <var>N</var>
                                 supplied arguments are matched to the first <var>N</var> declared parameters.</p></item>
                              <item><p>If <var>N</var> &gt; <var>M</var>, the values of the <var>M</var>th and subsequent arguments
                              are sequence-concatenated into a single value, which is matched to the <var>M</var>th
                              declared parameter. This means, for example, that if a variadic function <var>F</var>
                              with two declared parameters is called using a static function call of the form 
                                 <code>F(a, b, c)</code>, then the call is effectively equivalent to
                              <code>F(a, (b, c))</code>.</p>
                              <note><p>The combined value <code>(b, c)</code> must satisfy the required type
                              for the relevant parameter, after the coercion rules are applied.</p></note>
                              </item>
                           </olist>
                        </item>-->
                           <item>
                              <p>Any keyword arguments in <var>FC</var> are then matched to
                           parameters (whether required or optional) in <var>FD</var> by comparing the keyword
                           used in <var>FC</var> with the paramater name declared in <var>FD</var>.
                           Each keyword must match the name of a declared parameter <errorref class="ST" code="0017"/>, 
                           and this must be one that has not already
                           been matched to a positional argument. <errorref class="ST" code="0017"/>.</p>
                           </item>
                           <item>
                              <p>If any required parameter has not been matched to any argument in <var>FC</var>
                           by applying the above rules, a static error is reported <errorref class="ST" code="0017"/>
                              </p>
                           </item>
                           <item>
                              <p>If any optional parameter has not been matched to any argument in <var>FC</var>
                           by applying the above rules, then the parameter is matched to the 
                           default value expression for that parameter in <var>FD</var>.</p>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>
                          Each argument expression established by the above rules is evaluated with respect to DC.
                          The order of argument evaluation is <termref def="dt-implementation-dependent"/> and it is not
                        required that an argument be evaluated if the function body can be evaluated without evaluating
                        that argument.</p>
                        <note>
                           <p>All argument expressions, including default value expressions, are evaluated in the dynamic
                     context of the function call. It is therefore possible to use a default value expression such as 
                     <code nobreak="false">.</code>, or <code nobreak="false">/</code>, or <code nobreak="false">fn:current-dateTime()</code>, whose value depends on the
                     dynamic context of the function call.</p>
                        </note>
                        <p>If the expression used for the default value of a parameter has no dependencies on the dynamic
                     context, then an implementation <rfc2119>may</rfc2119> choose to reuse the same value on repeated
                     function calls rather than re-evaluating it on each function call.</p>
                        <note>
                           <p>This is relevant, for example, if the expression constructs new nodes.</p>
                        </note>
                     </item>
                     <item>
                        <p>The result of evaluating the argument expression is converted to the required type (the
                     declared type associated with the corresponding parameter in the function declaration, defaulting
                     to <code nobreak="false">item()*</code>) by applying the <termref def="dt-coercion-rules"/>.</p>
                        <p>
                           <phrase diff="add" at="2023-12-12">This applies both to explicitly supplied arguments, and
                        to values obtained by evaluating default value expressions. In both cases a type
                        error will be raised if the value (after coercion) does not match the required type.</phrase>
                        </p>
                        <!--<p>In the case of a <termref def="dt-variadic"/> function, the coercion rules are applied
                     to the sequence-concatenation of any supplied arguments that are combined to provide a value
                     for the parameter.</p>-->
                     </item>
                     <item>
                        <p>The result of the function call is obtained as follows:</p>
                        <ulist>
                           <item>
                              <p>
                                 <var>FD</var>’s <phrase diff="chg" at="2023-03-11">body</phrase> is invoked
                                      in an implementation-dependent way.
                                      The processor makes the following information
                                      available to that invocation:
                                      
                                    </p>
                              <ulist>
                                 <item>
                                    <p>The converted argument values;</p>
                                 </item>
                                 <item diff="del" at="2023-03-11">
                                    <p diff="del" at="2023-03-11">
                                                An empty set of nonlocal variable bindings; and</p>
                                 </item>
                                 <item>
                                    <p diff="chg" at="2023-03-11">If the function is <termref def="dt-context-dependent"/>,
                                          the static context <var>SC</var> and dynamic context <var>DC</var> of the function call.
                                           </p>
                                 </item>
                              </ulist>
                              <p diff="del" at="2023-03-11">
                                      How this information is used is <termref def="dt-implementation-defined">implementation-defined</termref>.
                                      An API used to call external functions must state
                                      how the static and dynamic contexts are provided
                                      to a function that is called.
                                      The F&amp;O specification states how the static and dynamic contexts
                                      are used in each function that it defines. 
                                      
                                       </p>
                           </item>
                           <item>
                              <p>The result is converted to the required type (the
                                             declared return type in the function declaration, defaulting
                                             to <code nobreak="false">item()*</code>) by applying the <termref def="dt-coercion-rules"/>.</p>
                              <p>The result of applying the coercion rules is either an instance of <var>FD</var>’s return type
                                      or a dynamic error.
                                      This result is then the result of evaluating <var>FC</var>.</p>
                              <note>
                                 <p>A host language may define alternative rules for processing the result, especially
                                      in the case of external functions implemented using a non-XDM type system.</p>
                              </note>
                           </item>
                           <item>
                              <p>
                                      Errors raised by system functions are defined in
                                      <bibref ref="xpath-functions-40"/>.
                                    </p>
                           </item>
                           <item role="xquery">
                              <p>
                                      Errors raised by external functions are
                                      <termref def="dt-implementation-defined">implementation-defined</termref>
                                      (see <specref ref="id-consistency-constraints"/>).
                                    </p>
                           </item>
                        </ulist>
                        <example>
                           <head>A System Function</head>
                           <p>The following function call uses the function 
                                  <xspecref spec="FO40" ref="func-base-uri"/>.  Use of <code nobreak="false">SC</code> and <code nobreak="false">DC</code> and errors raised by this function are all defined in 
                                  <bibref ref="xpath-functions-40"/>.</p>
                           <eg role="parse-test" xml:space="preserve">base-uri()</eg>
                        </example>
                     </item>
                  </olist>
               </div4>
            </div3>
            <div3 id="id-dynamic-functions">
               <head>Function Items</head>
               <p>A <termref def="dt-function-item"/> is an XDM
            value that can be bound to a variable, or manipulated in various ways by XQuery 4.0 expressions.
            The most significant such expression is a <termref def="dt-dynamic-function-call"/>, which supplies
            values of arguments and evaluates the function to produce a result.</p>
               <p>The syntax of dynamic function calls is defined in <specref ref="id-dynamic-function-invocation"/>.</p>
               <p>A number of constructs can be used to produce a <termref def="dt-function-item"/>, notably:</p>
               <ulist>
                  <item>
                     <p>A <term>named function reference</term> (see <specref ref="id-named-function-ref"/>)
               constructs a function item by reference to <termref def="dt-function-definition">function definitions</termref>
                  in the static context. For example, <function>fn:node-name#1</function>
               returns a function item whose effect is to call the static <function>fn:node-name</function> function
               with one argument.</p>
                  </item>
                  <item>
                     <p>An <term>inline function</term> (see <specref ref="id-inline-func"/>
                        <!-- and <specref ref="id-lambda-expressions"/>-->)
                  constructs a function item whose <phrase diff="chg" at="2023-03-11">body</phrase> is defined locally. For example, the
               construct <code nobreak="false">fn($x) { $x + 1 }</code> returns a function item whose effect is to increment
               the value of the supplied argument.</p>
                  </item>
                  <item>
                     <p>A <term>partial function application</term> (see 
                  <specref ref="id-partial-function-application"/>) derives one function item from another by supplying
               the values of some of its arguments. For example, <code nobreak="false">fn:ends-with(?, ".txt")</code> returns
               a function item with one argument that tests whether the supplied string ends with the substring
                  <code nobreak="false">".txt"</code>.</p>
                  </item>
                  <item>
                     <p>Maps and arrays are also function items. See <specref ref="id-map-constructors"/>
               and <specref ref="id-array-constructors"/>.</p>
                  </item>
                  <item diff="add" at="B">
                     <p>The <function>fn:function-lookup</function> function can be called to discover functions
               that are present in the <termref def="dt-dynamic-context"/>.</p>
                  </item>
                  <item diff="add" at="B">
                     <p>The <function>fn:load-xquery-module</function> function can be called to load functions
                  dynamically from an external XQuery library module.</p>
                  </item>
                  <item diff="add" at="B">
                     <p>Some system functions such as <function>fn:random-number-generator</function> 
                  and <function>fn:op</function> return a <termref def="dt-function-item"/> as their result.</p>
                  </item>
               </ulist>
               <p>These constructs are described in detail in the following sections, or in
               <bibref ref="xpath-functions-40"/>.</p>
            </div3>
            <div3 id="id-dynamic-function-invocation">
               <head>Dynamic Function Calls</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-DynamicFunctionCall">
                     <lhs>DynamicFunctionCall</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-DynamicFunctionCall-PostfixExpr">
                     <lhs>PostfixExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-DynamicFunctionCall-PositionalArgumentList">
                     <lhs>PositionalArgumentList</lhs>
                     <rhs>"("  <nt def="prod-xquery40-PositionalArguments">PositionalArguments<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-DynamicFunctionCall-PositionalArguments">
                     <lhs>PositionalArguments</lhs>
                     <rhs>(<nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-DynamicFunctionCall-Argument">
                     <lhs>Argument</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholder<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-DynamicFunctionCall-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-DynamicFunctionCall-ArgumentPlaceholder">
                     <lhs>ArgumentPlaceholder</lhs>
                     <rhs>"?"</rhs>
                  </prod>
               </scrap>
               <p>
                  A <termref def="dt-dynamic-function-call"/>
                     consists of a base expression that returns the function and a
                     parenthesized list of zero or more arguments (<termref def="dt-arg-expr">argument expressions</termref> or
                     ArgumentPlaceholders).
               </p>
               <p>
                  A dynamic function call is evaluated as described in
                  <specref ref="id-eval-dynamic-function-call"/>.
               </p>
               <p>The following are examples of dynamic function calls:</p>
               <ulist>
                  <item>
                     <p>This example calls the function contained in <code nobreak="false">$f</code>, passing the arguments 2 and 3:
                        <eg role="parse-test" xml:space="preserve">$f(2, 3)</eg>
                     </p>
                  </item>
                  <item>
                     <p>This example fetches the second item from sequence <code nobreak="false">$f</code>, treats it as a function and calls it, passing an <code nobreak="false">xs:string</code> argument:
                        <eg role="parse-test" xml:space="preserve">$f[2]("Hi there")</eg>
                     </p>
                  </item>
                  <item>
                     <p>This example calls the function <code nobreak="false">$f</code> passing no arguments, and filters the result with a positional predicate:
                        <eg role="parse-test" xml:space="preserve">$f()[2]</eg>
                     </p>
                  </item>
               </ulist>
               <note diff="add" at="A">
                  <p>Arguments in a dynamic function call are always supplied positionally.</p>
               </note>
               <div4 id="id-eval-dynamic-function-call">
                  <head>Evaluating Dynamic Function Calls</head>
                  <changes>
                     <change issue="1240">A dynamic function call can now be applied to a sequence of functions, and in particular
               to the empty sequence. This makes it easier to chain a sequence of calls.</change>
                     <change issue="2500">The coercion rules now apply to the target of a dynamic function call, making
                  it possible to supply a JNode that wraps an array or map.</change>
                  </changes>
                  <p>This section applies to dynamic function calls whose arguments do not include
            an <code nobreak="false">ArgumentPlaceholder</code>. For function calls that include a placeholder,
            see <specref ref="id-partial-function-application"/>.</p>
                  <p diff="add" at="B">A <termref def="dt-dynamic-function-call"/>
            is an expression that is evaluated by calling a <termref def="dt-function-item"/>, which is
            typically obtained dynamically.</p>
                  <p>
                      When a dynamic function call <var>FC</var> is evaluated,
                      the result is obtained as follows:
                    </p>
                  <olist>
                     <item>
                        <p>
                          The base expression of the function call is evaluated,
                          and the <termref def="dt-coercion-rules"/> are applied
                          to the result with a required type of <code nobreak="false">function(*)*</code> (a sequence
                        of zero or more function items).
                     </p>
                     </item>
                     <item>
                        <p>The result of the dynamic function call is the <termref def="dt-sequence-concatenation"/>
                        of the results of applying each function item individually, retaining order. That is, the
                        result of <code nobreak="false">
                              <var>F</var>(<var>X</var>, <var>Y</var>, ...)</code> is 
                        <code nobreak="false">for $FI in <var>F</var> return <var>$FI</var>(<var>X</var>, <var>Y</var>, ...)</code>.
                        The result of a dynamic function call applied to a single function item <var>FI</var> is defined
                        by the rules that follow.
                     </p>
                     </item>
                     <item>
                        <p>
                           <errorref class="TY" code="0004"/>.
                              If the arity of <var>FI</var> does not match the number of arguments in the <code nobreak="false">ArgumentList</code>,
                              a type error is raised
                              <errorref class="TY" code="0004"/>.
                            </p>
                     </item>
                     <item>
                        <p>
                           <termref def="dt-arg-expr">Argument expressions</termref> are evaluated, 
                        producing <term>argument values</term>. The order of argument evaluation is <termref def="dt-implementation-dependent">implementation-dependent</termref> and an argument need not be evaluated 
                        if the function body can be evaluated without evaluating that argument.</p>
                     </item>
                     <item>
                        <p>
                          Each argument value is converted
                          to the corresponding parameter type in <var>FI</var>’s signature
                          by applying the <termref def="dt-coercion-rules"/>, resulting in a
                        <term>converted argument value</term>
                        </p>
                     </item>
                     <item>
                        <p>If <var>FI</var> is a map, it is evaluated as described in <specref ref="id-map-lookup"/>.</p>
                     </item>
                     <item>
                        <p>If <var>FI</var> is an array, it is evaluated as described in <specref ref="id-array-lookup"/>.</p>
                     </item>
                     <item>
                        <p>
                                  If <var>FI</var>’s <phrase diff="chg" at="2023-03-11">body</phrase> is 
                                  
                                  an XQuery 4.0 expression
                                  
                                    (for example, if <var>FI</var> is
                                    <phrase role="xquery">a <termref def="dt-udf">user-defined function</termref> or</phrase>
                                    an <termref def="dt-anonymous-function">anonymous function</termref>,
                                    or a
                                    <termref def="dt-partially-applied-function">partial application</termref>
                                    of such a function):
                                  
                                </p>
                        <olist>
                           <item>
                              <p>
                                 <var>FI</var>’s <phrase diff="chg" at="2023-03-11">body</phrase> 
                                      is evaluated.
                                      
                                        The static context for this evaluation
                                        is the static context of the XQuery 4.0 expression.
                                      
                                      The dynamic context for this evaluation is obtained
                                      by taking the dynamic context of the
                                      <phrase role="xquery">module</phrase>
                                          
                                      that contains the <code nobreak="false">FunctionBody</code>, and
                                      making the following changes:
                                    </p>
                              <ulist>
                                 <item>
                                    <p>
                                          The <termref def="dt-focus">focus</termref>
                                          (context value, context position, and context size)
                                          is <xtermref spec="DM40" ref="dt-absent"/>.
                                        </p>
                                 </item>
                                 <item>
                                    <p>
                                          In the <termref def="dt-variable-values">variable values</termref> component of the dynamic context,
                                          each converted argument value is bound to the
                                          corresponding parameter name.
                                        </p>
                                    <p>
                                       <phrase diff="chg" at="B">When this is done,
                                          the converted argument values retain
                                          their <termref def="dt-dynamic-type">dynamic types</termref>,
                                          even where these are <termref def="dt-subtype">subtypes</termref> 
                                          of the declared parameter types.</phrase>
                                          For example, a function with
                                          a parameter <code nobreak="false">$p</code> of type <code nobreak="false">xs:decimal</code>
                                          can be called with an argument of type <code nobreak="false">xs:integer</code>,
                                          which is derived from <code nobreak="false">xs:decimal</code>.
                                          During the processing of this function
                                          call, the value of <code nobreak="false">$p</code> inside the body of the function 
                                          retains its <termref def="dt-dynamic-type"/> of <code nobreak="false">xs:integer</code>.
                                        </p>
                                 </item>
                                 <item>
                                    <p>
                                       <var>FI</var>’s nonlocal variable bindings
                                          are also added to the <termref def="dt-variable-values">variable values</termref>.
                                          (Note that the names of the nonlocal variables
                                          are by definition disjoint from the parameter names,
                                          so there can be no conflict.)
                                        </p>
                                 </item>
                              </ulist>
                           </item>
                           <item>
                              <p>
                                      The value returned by evaluating the function body
                                      is then converted to the declared return type of <var>FI</var>
                                      by applying the
                                      <termref def="dt-coercion-rules">coercion rules</termref>.
                                      The result is then the result of evaluating <var>FC</var>.
                                    </p>
                              <p>
                                      As with argument values,
                                      the value returned by a function
                                      retains its <termref def="dt-dynamic-type"/>,
                                      which may be a <termref def="dt-subtype"/> of the declared return type of <var>FI</var>.
                                      For example, a function that has
                                      a declared return type of <code nobreak="false">xs:decimal</code>
                                      may in fact return a value of dynamic type <code nobreak="false">xs:integer</code>.
                                    </p>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>                                  
                                  If the implementation of <var>FI</var> is
                                  not an XQuery 4.0 expression
                                  (for example, if <var>FI</var> is
                                  a <termref def="dt-system-function">system function</termref>
                           <phrase role="xquery">or an <termref def="dt-external-function">external function</termref>
                           </phrase>), 
                                    the <phrase diff="chg" at="2023-03-11">body</phrase> of the function is
                                       evaluated, and the result is converted
                                       to the declared return type, in the same way as for a 
                                       static function call (see <specref ref="id-function-calls"/>).</p>
                        <p>Errors may be raised in the same way.</p>
                     </item>
                  </olist>
                  <example>
                     <head>Derived Types and Nonlocal Variable Bindings</head>
                     <p>
                        <code nobreak="false">$incr</code> is a nonlocal variable that is available within the function because 
                                       its variable binding has been added to the variable values of the function.  
                                       Even though the parameter and return type of this function are both <code nobreak="false">xs:decimal</code>,
                                  the more specific type <code nobreak="false">xs:integer</code> is preserved in both cases.</p>
                     <eg role="parse-test" xml:space="preserve">
let $incr := 1
let $f := function($i as xs:decimal) as xs:decimal { $i + $incr }
return $f(5)</eg>
                  </example>
                  <example>
                     <head>Using the Context Value in an Anonymous Function</head>
                     <p>The following example will raise a <termref def="dt-type-error"/>
                        <errorref class="DY" code="0002"/>:</p>
                     <eg role="parse-test" xml:space="preserve">
let $vat := function() { @vat + @price }
return doc('wares.xml')/shop/article/$vat()</eg>
                     <p>Instead, the context value can be used as an argument to the anonymous function:</p>
                     <eg role="parse-test" xml:space="preserve">
let $vat := function($art) { $art/@vat + $art/@price }
return doc('wares.xml')/shop/article/$vat(.)</eg>
                     <p>Alternatively, the value can be referenced as a nonlocal variable binding:</p>
                     <eg role="parse-test" xml:space="preserve">
let $ctx := doc('wares.xml')/shop/article
let $vat := function() { for $a in $ctx return $a/@vat + $a/@price }
return $vat()
</eg>
                     <p>Finally, a <termref def="dt-focus-function"/> can be used.
                                       This binds the value of the argument to the context value within the function body:</p>
                     <eg role="parse-test" xml:space="preserve">
let $vat := function { @vat + @price }
return $vat(doc('wares.xml')/shop/article)
</eg>
                  </example>
                  <example>
                     <head>Applying multiple functions</head>
                     <p>A dynamic function call can call zero or more functions with the same arguments, returning
               the <termref def="dt-sequence-concatenation"/> of the result. For example:</p>
                     <eg role="parse-test" xml:space="preserve">(abs#1, round#1, floor#1, ceiling#1)(3.2)</eg>
                     <p>returns the sequence <code nobreak="false">(3.2, 3, 3, 4)</code>.</p>
                     <p>A common case for supplying a sequence of functions arises when the functions are arrays.
               For example:</p>
                     <eg xml:space="preserve">csv-to-arrays( string-join(("a,b,c", "p,q,r", "x,y,z"), char(10)) ) (2)</eg>
                     <p>returns the sequence <code nobreak="false">("b", "q", "y")</code>.</p>
                     <p>If the base expression evaluates to the empty sequence, the result
               is the empty sequence.</p>
                  </example>
                  <example>
                     <head>Invoking a map wrapped in a JNode</head>
                     <p>Consider the JSON text:</p>
                     <eg xml:space="preserve">[
   { "first": "John", "last": "Lennon"},
   { "first": "Paul", "last": "McCartney"},
   { "first": "George", "last": "Harrison"},
   { "first": "Ringo", "last": "Starr"}
]</eg>
                     <p>And let <code nobreak="false">$Beatles</code> be the result of parsing this using <function>fn:parse-json</function>.</p>
                     <p>Then the result of the function call <code nobreak="false">$Beatles/*("first")</code> is
               <code nobreak="false">("John", "Paul", "George", "Ringo")</code>.</p>
                     <p>Explanation: the value of <code nobreak="false">$Beatles</code> is an array. This is implicitly converted to a JNode
               because it appears as the left-hand operand of the <code nobreak="false">/</code> operator. The result of the expression
               <code nobreak="false">$Beatles/*</code> is therefore a sequence of four JNodes, each of them having a map as its 
                  <term>·content·</term> property.
               When the target of a dynamic function call is a sequence of JNodes, the sequence is coerced to type <code nobreak="false">function(*)*</code>,
               delivering a sequence comprising the four maps. These are called as functions, returning the values of the
               corresponding entries as <code nobreak="false">xs:string</code> items.</p>
                     <p>The same result could be achieved with the expression <code nobreak="false">$Beatles/*/first/jvalue()</code>.</p>
                  </example>
               </div4>
            </div3>
            <div3 id="id-partial-function-application">
               <head>Partial Function Application</head>
               <p>
                  <termdef term="partial function application"
                           id="dt-partial-function-application">
                     A <termref def="dt-static-function-call">static</termref> or 
                     <termref def="dt-dynamic-function-call">dynamic</termref>
                     function call is a <term>partial function application</term>
                     if one or more arguments is an <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholder<!--$spec = xquery40--></nt>.</termdef>
               </p>
               <p>The rules for partial function application in static function calls and dynamic function
               calls have a great deal in common, but they are stated separately below for clarity.</p>
               <p>Partial function application delivers
                  <termref def="dt-function-item">function items</termref>, whose
                  arity is equal to the number of placeholders in the call.</p>
               <p>A static partial function application always delivers one <termref def="dt-function-item"/>.
               A dynamic partial function application delivers one <termref def="dt-function-item"/> for each
               <termref def="dt-function-item"/> in the input.</p>
               <p>More specifically, each function item in the result of the partial function application is 
                  a <termref def="dt-partially-applied-function">partially applied function</termref>.
                  <termdef term="partially applied function" id="dt-partially-applied-function">A <term>partially applied function</term>
                  is a function created by  <termref def="dt-partial-function-application">partial function application</termref>.</termdef>
               </p>
               <p>For static function calls, the result is obtained as follows:</p>
               <olist>
                  <item>
                     <p>The <termref def="dt-function-definition"/>
                        <var>FD</var> to be partially applied
                        is determined in the same way as for a static function call without placeholders, 
                        as described in <specref ref="id-function-calls"/>.
                        For this purpose an <code nobreak="false">ArgumentPlaceholder</code> contributes to the count of
                        arguments.</p>
                  </item>
                  <item>
                     <p>The parameters of <var>FD</var> are classified into three categories:</p>
                     <ulist>
                        <item>
                           <p>Parameters that map to a placeholder, referred to as <term>placeholder parameters</term>.</p>
                        </item>
                        <item>
                           <p>Parameters for which an explicit value is given in the function call (either
                        positionally or by keyword), referred to as <term>explicitly supplied parameters</term>.</p>
                        </item>
                        <item>
                           <p>Parameters (which are necessarily optional parameters) for which no corresponding
                        argument is supplied, either as a placeholder or with an explicit value. These are referred to
                        as <term>defaulted parameters</term>.</p>
                        </item>
                     </ulist>
                     <note>
                        <p>A partial function application need not have any explicitly supplied parameters.
                        For example, the partial function application <code nobreak="false">fn:string(?)</code>
                        is allowed; it has exactly the same effect as the <termref def="dt-named-function-ref"/>
                           <function>fn:string#1</function>. </p>
                     </note>
                  </item>
                  <item>
                     <p>Explicitly supplied parameters and defaulted parameters are evaluated and 
                        converted to the required type using the rules for a static function call.
                        This may result in an error being raised.</p>
                     <p diff="add" at="2023-12-12">A type error is raised if any of the explicitly supplied or defaulted
                        parameters, after applying the
                        <termref def="dt-coercion-rules"/>, does not match the required type 
                        of the corresponding parameter.</p>
                     <p diff="add" at="2023-12-12">In addition, a dynamic error <rfc2119>may</rfc2119> 
                        be raised if any of the explicitly supplied or defaulted parameters does not match other constraints on the
                        value of that parameter (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>
                     <p diff="add" at="2023-12-12">In all cases the error code is the same as for a static
                        function call supplying the same invalid value(s).</p>
                     <p diff="add" at="2024-02-02">In the particular case where all the supplied arguments
                     are placeholders, the error behavior <rfc2119>should</rfc2119> be the same as
                     for an equivalent <termref def="dt-named-function-ref"/>: for example, <function>fn:id#1</function>
                     fails if there is no context node, and <code nobreak="false">fn:id(?)</code>
                        <rfc2119>should</rfc2119>
                     fail likewise.</p>
                  </item>
                  <item>
                     <p>
                        The result is a <termref def="dt-partially-applied-function">partially applied function</termref> having
                        the following properties (which are defined in <xspecref spec="DM40" ref="function-items"/>):
                     </p>
                     <ulist>
                        <item>
                           <p>
                              <term>name</term>: The name of <var>FD</var> if all parameters map
                              to placeholders, that is, if the partial function application is
                              equivalent to the corresponding <termref def="dt-named-function-ref"/>.
                              Otherwise, the name is absent.
                           </p>
                        </item>
                        <item>
                           <p diff="add" at="2023-05-25">
                              <term>identity</term>: A new function
                           identity distinct from the identity of any other function item.</p>
                           <note>
                              <p>See also <specref ref="id-function-identity"/>.</p>
                           </note>
                        </item>
                        <item>
                           <p>
                              <term>arity</term>: The number of placeholders in the function call.</p>
                        </item>
                        <item>
                           <p>
                              <term>signature</term>: The parameters in the returned function
                              are the parameters of <var>FD</var>
                              that have been identified as placeholder parameters,
                              retaining the order in which the placeholders appear in the
                              function call. The result type of the returned function
                              is the same as the result type of <var>FD</var>.</p>
                           <p>An implementation which can determine a more specific signature (for example, 
                              through use of type analysis) is permitted to do so.
                           </p>
                        </item>
                        <item>
                           <p>
                              <term>annotations</term>: The annotations of 
                           <var>FD</var>.</p>
                        </item>
                        <item>
                           <p>
                              <term>body</term>: The body of <var>FD</var>.</p>
                        </item>
                        <item>
                           <p>
                              <term>captured context</term>: The
                              static and dynamic context of the function call, augmented,
                              for each explicitly supplied parameter and each defaulted parameter, with
                              a binding of the converted argument value
                              to the corresponding parameter name.
                           </p>
                        </item>
                     </ulist>
                     <note>
                        <p>A partial function application can be used to change the order
                           of parameters, for example <code nobreak="false">fn:contains(substring := ?, value := ?)</code>
                           returns a function item that is equivalent to <function>fn:contains#2</function>,
                           but with the order of arguments reversed.</p>
                     </note>
                     <example>
                        <head>Partial Application of a System Function</head>
                        <p>The following partial function application creates a function 
                           item that computes the sum of squares of a sequence.</p>
                        <eg role="parse-test" xml:space="preserve">let $sum-of-squares := fold-right(?, 0, function($a, $b) { $a*$a + $b })
return $sum-of-squares(1 to 3)</eg>
                        <p>
                           <code nobreak="false">$sum-of-squares</code> is an anonymous function. It has one parameter, named <code nobreak="false">$seq</code>, which is taken from the corresponding parameter in <function>fn:fold-right</function> (the other two parameters are fixed). The implementation is the implementation of <function>fn:fold-right</function>, which is a context-independent system function. The nonlocal bindings contain the fixed bindings for the second and third parameters of <function>fn:fold-right</function>.</p>
                     </example>
                  </item>
               </olist>
               <p>For dynamic function calls,  the result is obtained as follows:</p>
               <olist>
                  <item>
                     <p>
                          The base expression of the function call is evaluated.
                          If this is not of type <code nobreak="false">function(*)*</code> (a sequence
                        of zero or more function items) then a type error is raised.
                     </p>
                  </item>
                  <item>
                     <p>The result of the dynamic function call is the <termref def="dt-sequence-concatenation"/>
                        of the results of partial applying each function item, retaining order. That is, the
                        result of <code nobreak="false">
                           <var>F</var>(<var>X</var>, <var>Y</var>, ...)</code> is 
                        <code nobreak="false">for $FI in <var>F</var> return <var>$FI</var>(<var>X</var>, <var>Y</var>, ...)</code>.
                        The result of a dynamic function call applied to a single function item <var>FI</var> is defined
                        by the rules that follow.
                     </p>
                  </item>
                  <item>
                     <p>An <code nobreak="false">ArgumentPlaceholder</code> contributes to the count of
                        arguments.</p>
                  </item>
                  <item>
                     <p>The parameters of <var>FI</var> are classified into two categories:</p>
                     <ulist>
                        <item>
                           <p>Parameters that map to a placeholder, referred to as <term>placeholder parameters</term>.</p>
                        </item>
                        <item>
                           <p>Parameters for which an explicit value is given in the function call, 
                           referred to as <term>supplied parameters</term>.</p>
                        </item>
                     </ulist>
                     <note>
                        <p>A partial function application need not have any explicitly supplied parameters.
                        For example, if <code nobreak="false">$f</code> is a function with arity 2, then
                           the partial function application <code nobreak="false">$f(?, ?)</code> returns
                           a function that has exactly the same effect as <code nobreak="false">$f</code>. </p>
                     </note>
                  </item>
                  <item>
                     <p>Arguments corresponding to supplied parameters are evaluated
                        and converted to the required
                     type of the parameter, using the rules for dynamic function calls.</p>
                     <p diff="add" at="2023-12-12">A type error is raised if any of the supplied
                        parameters, after applying the
                        <termref def="dt-coercion-rules"/>, does not match the required type.</p>
                     <p diff="add" at="2023-12-12">In addition, a dynamic error <rfc2119>may</rfc2119> 
                     be raised if any of the supplied parameters does not match other constraints on the
                     value of that parameter (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 parameters).</p>
                     <p diff="add" at="2023-12-12">In both cases the error code is the same as for a dynamic
                     function call supplying the same invalid value.</p>
                  </item>
                  <item>
                     <p>
                              The result of the partial function application is a  <termref def="dt-partially-applied-function">partially applied function</termref> with
                              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>arity</term>: The number of placeholders in the function call.</p>
                        </item>
                        <item>
                           <p>
                              <term>signature</term>:
                                  The signature of <var>FI</var>,
                                  removing the types of supplied parameters.
				  
				                      An implementation which can determine a more specific signature (for example, 
				                      through use of type analysis) is permitted to do so.
                                </p>
                        </item>
                        <item>
                           <p>
                              <term>annotations</term>: The annotations of <var>FI</var>.</p>
                        </item>
                        <item>
                           <p>
                              <term>body</term>: The body of <var>FI</var>.
                                </p>
                        </item>
                        <item>
                           <p>
                              <term>captured context</term>: the
                                    captured context of <var>FI</var>, augmented,
                                  for each supplied parameter, with
                                  a binding of the converted argument value
                                  to the corresponding parameter name.
                                </p>
                        </item>
                     </ulist>
                     <note>
                        <p>In a dynamic partial function application, argument keywords
                                 are not available, so it is not possible to change the order of parameters.</p>
                     </note>
                     <example>
                        <head>Partial Application of an Anonymous Function</head>
                        <p>In the following example, <code nobreak="false">$f</code> is an anonymous function, and <code nobreak="false">$paf</code> is a partially applied function created from <code nobreak="false">$f</code>.</p>
                        <eg role="parse-test" xml:space="preserve">
let $f := function($seq, $delim) { fold-left($seq, "", concat(?, $delim, ?)) }
let $paf := $f(?, ".")
return $paf(1 to 5)
</eg>
                        <p>
                           <code nobreak="false">$paf</code> is also an anonymous function.  It has one parameter, named <code nobreak="false">$delim</code>, which is taken from the corresponding parameter in <code nobreak="false">$f</code>
                              (the other parameter is fixed).  The implementation of <code nobreak="false">$paf</code> is the implementation of <code nobreak="false">$f</code>, which is <code nobreak="false">fn:fold-left($seq, "", fn:concat(?, $delim, ?))</code>.  This implementation is associated with the <code nobreak="false">SC</code> and <code nobreak="false">DC</code> of the original expression in <code nobreak="false">$f</code>.  The nonlocal bindings associate the value <code nobreak="false">"."</code> with the parameter <code nobreak="false">$delim</code>.</p>
                     </example>
                  </item>
               </olist>
               <p>Partial function application never returns a map or an array.  If <code nobreak="false">$f</code> is a map or an array, then <code nobreak="false">$f(?)</code> is 
                  a partial function application that returns a function, but the function it returns is neither a map nor an array.</p>
               <example>
                  <head>Partial Application of a Map</head>
                  <p>The following partial function application converts a map to an equivalent function that is not a map.</p>
                  <eg role="parse-test" xml:space="preserve">let $a := { "A": 1, "B": 2 }(?)
return $a("A")</eg>
               </example>
            </div3>
            <!-- ******************************************************************** -->
            <div3 id="id-named-function-ref">
               <head>Named Function References</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-NamedFunctionRef">
                     <lhs>NamedFunctionRef</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "#"  <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-NamedFunctionRef-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-NamedFunctionRef-IntegerLiteral">
                     <lhs>IntegerLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-NamedFunctionRef-Digits">
                     <lhs>Digits</lhs>
                     <rhs>
                        <nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>  |  "_")*  <nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-NamedFunctionRef-DecDigit">
                     <lhs>DecDigit</lhs>
                     <rhs>[0-9]</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>
               </scrap>
               <p>
                  <termdef term="named function reference" id="dt-named-function-ref">
          A <term>named function reference</term> is an instance of the production
                  <nt def="doc-xquery40-NamedFunctionRef">NamedFunctionRef<!--$spec = xquery40--></nt>: 
                  it is an expression (written <code nobreak="false">name#arity</code>)
                  which evaluates to a <termref def="dt-function-item"/>, the details
                  of the function item being based on the properties of a <termref def="dt-function-definition"/>
                  in the <termref def="dt-static-context"/>.</termdef>
               </p>
               <p>The name and arity of the required function are known statically.</p>
               <p>The EQName is expanded using the <termref def="dt-default-function-namespace-rule"/>.</p>
               <p>The <termref def="dt-expanded-qname"/> and arity must correspond to a <termref def="dt-function-definition"/>
               present in the <termref def="dt-static-context">static context</termref>.
            <phrase diff="add" at="variadicity">More specifically, for a named function reference <code nobreak="false">F#N</code>,
               there must be a <termref def="dt-function-definition"/> in the <termref def="dt-statically-known-function-definitions"/>
               whose name matches <var>F</var>, and whose <termref def="dt-arity-range"/> includes <var>N</var>
                  </phrase>.
               Call this <termref def="dt-function-definition"/>
                  <var>FD</var>.</p>
               <p diff="chg" at="2023-03-11">If <var>FD</var> is
          <termref def="dt-context-dependent"/> for the given arity, then the returned function item has
               a captured context comprising
          the static and dynamic context of the named function reference.</p>
               <note diff="chg" at="2023-03-11">
                  <p>In practice, it is necessary to retain only those
            parts of the static and dynamic context that can affect the outcome. These means it is 
            unnecessary to retain parts of the context that no <termref def="dt-system-function"/>
            depends on (for example, local variables), or parts that are invariant within an
            execution scope (for example, the implicit timezone).</p>
               </note>
               <example diff="add" at="B">
                  <head>A Context-Dependent Named Function Reference</head>
                  <p>Consider:</p>
                  <eg role="parse-test" xml:space="preserve">let $f := &lt;foo/&gt;/fn:name#0 return &lt;bar/&gt;/$f()</eg>
                  <p>The function <code nobreak="false">fn:name()</code>, with no arguments, returns the name of the context node. The function
               item delivered by evaluating the expression <function>fn:name#0</function> returns the name of the element that was the
               context node at the point where the function reference was evaluated (that is, the <code nobreak="false">&lt;foo&gt;</code> element).
               This expression therefore returns <code nobreak="false">"foo"</code>, not <code nobreak="false">"bar"</code>.</p>
               </example>
               <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 <errorref class="DY" code="0002" type="type"/> is raised for the expression <function>fn:name#0</function>
                  if the context item is absent, and <xerrorref spec="FO" class="DC" code="0001" type="dynamic"/> is raised for the call <function>fn:id#1</function> if the context item is not a 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>
               <p>If the <termref def="dt-expanded-qname">expanded QName</termref> and arity in a named function reference do not match the 
               name and <termref def="dt-arity-range"/> of a <termref def="dt-function-definition"/> in the
          static context, a static error is raised <errorref class="ST" code="0017"/>.</p>
               <p diff="chg" at="variadicity">
            The value of a <code nobreak="false">NamedFunctionRef</code>
               is a <termref def="dt-function-item">function item</termref>
                  <var>FI</var> 
               obtained from <var>FD</var>
               as follows:
               <ulist>
                     <item>
                        <p>
                           <term>name</term>: The name of <var>FD</var>.</p>
                     </item>
                     <item>
                        <p diff="add" at="2023-05-25">
                           <term>identity</term>:</p>
                        <ulist>
                           <item>
                              <p>If <var>FD</var> is <termref def="dt-context-dependent"/> for the given arity, then a new function
                        identity distinct from the identity of any other function item.</p>
                              <note>
                                 <p>In the general case, a function reference to a context-dependent function
                           will produce different results every time it is evaluated, because the resulting function
                           item has a <term>captured context</term> 
                              (see <xspecref spec="DM40" ref="function-items"/>) that includes the dynamic context
                           of the particular evaluation. Optimizers, however, are allowed to detect cases where
                           the captured context happens to be the same, or where any variations are immaterial,
                           and where it is therefore safe to return the same function item each time. This might be
                           the case, for example, where the only context dependency of a function is on the default
                           collation, and the default collation for both evaluations is known to be the same.</p>
                              </note>
                           </item>
                           <item>
                              <p>Otherwise, a function identity that is the same as that produced by the evaluation
                           of any other named function reference with the same function name and arity.</p>
                              <p>This rule applies even across different 
                                <xtermref spec="FO40" ref="execution-scope">execution scopes</xtermref>:
                             for example if a parameter to a call to <function>fn:transform</function> is set to the
                             result of the expression <function>fn:abs#1</function>, then the function item passed as the parameter
                                value will be identical to that obtained by evaluating the expression <function>fn:abs#1</function>
                             within the target XSLT stylesheet.</p>
                              <p>This rule also applies when the target function definition is 
                           <xtermref spec="FO40" ref="dt-nondeterministic">nondeterministic</xtermref>. 
                           For example all evaluations of the named function reference <function>map:keys#2</function>
                           return identical function items, even though two evaluations of <function>map:keys</function>
                           with the same arguments may produce different results.</p>
                           </item>
                        </ulist>
                        <note>
                           <p>See also <specref ref="id-function-identity"/>.</p>
                        </note>
                     </item>
                     <item>
                        <p>
                           <term>arity</term>: As specified in the named function reference.</p>
                     </item>
                     <item>
                        <p>
                           <term>signature</term>: Formed from the required types of the first
                        <var>A</var> parameters of <var>FD</var>, and the function result type of
                        <var>FD</var>.</p>
                        <!--<p>In the case where <var>FD</var> is <termref def="dt-variadic"/> and
                     <var>A</var> exceeds the number of declared parameters in <var>FD</var>,
                     the required type of each excess parameter in the result is the same
                     as the required type of the last declared parameter of <var>FD</var>.</p>
                     <note><p>The required type of each
                     parameter of <function>fn:concat#3</function> is thus <code>xs:anyAtomicType*</code>,
                     which means that a call such as <code>concat#3(("a","b"), ("c","d"), ())</code>
                     is allowed.</p></note>-->
                     </item>
                     <item>
                        <p>
                           <term>annotations</term>: The annotations of 
                           <var>FD</var>.</p>
                     </item>
                     <item>
                        <p>
                           <term>body</term>: The body of <var>FD</var>.</p>
                     </item>
                     <item>
                        <p diff="chg" at="2023-03-12">
                           <term>captured context</term>: Comprises the
                        static and dynamic context of the named function reference, augmented with
                        bindings of the names of parameters of <var>FD</var> beyond the
                        <var>A</var>’th parameter, to their respective default values.</p>
                        <note diff="chg" at="2023-03-12">
                           <p>In practice, it is necessary to retain
                        only the parts of the context that the function actually depends on
                        (if any).</p>
                        </note>
                     </item>
                  </ulist>
               </p>
               <note diff="add" at="variadicity">
                  <p>Consider the system function <function>fn:format-date</function>,
            which has an arity range of 2 to 5. The named function reference <function>fn:format-date#3</function>
            returns a function item whose three parameters correspond to the first three parameters
            of <function>fn:format-date</function>; the remaining two arguments will take their default values.
               To obtain an arity-3 function that binds to arguments 1, 2, and 5 of <function>fn:format-date</function>,
            use the partial function application <code nobreak="false">format-date(?, ?, place := ?)</code>.</p>
               </note>
               <p>The following are examples of named function references:
          </p>
               <ulist>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">fn:abs#1</code> references the <function>fn:abs</function> function which takes a single argument.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">fn:concat#5</code> references the <function>fn:concat</function> function which takes 5 arguments.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">local:myfunc#2</code> references a function named <code nobreak="false">local:myfunc</code> which takes 2 arguments.</p>
                  </item>
               </ulist>
               <note diff="add" at="A">
                  <p>Function items, as values in the data model, have a fixed arity, and
            a dynamic function call always supplies the arguments positionally. <!--Although the base function
            referred to may be variadic, the result of evaluating the function reference is a function that
            has fixed arity. -->In effect, the result of evaluating <code nobreak="false">my:func#3</code> is the
            same as the result of evaluating the inline function expression <code nobreak="false">fn($x, $y, $z) { my:func($x, $y, $z) }</code>,
            except that the returned function has a name (it retains the name <code nobreak="false">my:func</code>).</p>
               </note>
            </div3>
            <div3 id="id-inline-func">
               <head>Inline Function Expressions</head>
               <changes>
                  <change issue="1192" PR="1197" date="2024-05-21">
                  In inline function expressions, the keyword <code nobreak="false">function</code> may be abbreviated
                  as <code nobreak="false">fn</code>.
               </change>
                  <change issue="503" PR="521" date="2023-05-30">New abbreviated syntax is introduced 
                     (<termref def="dt-focus-function"/>) 
                     for simple inline functions taking a single argument. 
                     An example is <code nobreak="false">fn { ../@code }</code>
                  </change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-InlineFunctionExpr">
                     <lhs>InlineFunctionExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  ("function"  |  "fn")  <nt def="prod-xquery40-FunctionSignature">FunctionSignature<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-FunctionBody">FunctionBody<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-Annotation">
                     <lhs>Annotation</lhs>
                     <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-FunctionSignature">
                     <lhs>FunctionSignature</lhs>
                     <rhs>"("  <nt def="prod-xquery40-ParamList">ParamList<!--$idref_lang_part = xquery40- --></nt>  ")"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-ParamList">
                     <lhs>ParamList</lhs>
                     <rhs>(<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ** ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-VarNameAndType">
                     <lhs>VarNameAndType</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-TypeDeclaration">
                     <lhs>TypeDeclaration</lhs>
                     <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-FunctionBody">
                     <lhs>FunctionBody</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-InlineFunctionExpr-EnclosedExpr">
                     <lhs>EnclosedExpr</lhs>
                     <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                  </prod>
               </scrap>
               <p>
                  <termdef term="inline function expression" id="dt-inline-func">An 
                  <term>inline function expression</term> is an instance of the
                  construct <nt def="doc-xquery40-InlineFunctionExpr">InlineFunctionExpr<!--$spec = xquery40--></nt>. When evaluated, 
                  an inline function expression creates
          an <termref def="dt-anonymous-function">anonymous function</termref>
          whose properties are defined directly in the inline function expression.</termdef> 
               An inline function expression defines the names and types of the parameters to the function,
          the type of the result, and the body of the function.</p>
               <p diff="add" at="2023-05-25">An <termref def="dt-inline-func"/> whose 
               <nt def="prod-xquery40-FunctionSignature">FunctionSignature<!--$spec = xquery40--></nt> is omitted
               is known as a <termref def="dt-focus-function"/>. Focus functions are 
               described in <specref ref="id-focus-functions"/>.</p>
               <p>
                  <termdef id="dt-anonymous-function" term="anonymous function">
             An <term>anonymous function</term> is a <termref def="dt-function-item"/> with no name.  
             Anonymous functions may be created, for example, by evaluating an inline function 
             expression or by partial function application.</termdef>
               </p>
               <p diff="add" at="2023-07-04">The keywords <code nobreak="false">function</code> and <code nobreak="false">fn</code> 
               are synonymous.</p>
               <p>The syntax allows the names and types of the function argument to be declared, along
           with the type of the result:</p>
               <eg xml:space="preserve">function($x as xs:integer, $y as xs:integer) as xs:integer { $x + $y }</eg>
               <p>The types can be omitted<phrase diff="add" at="2023-07-04">, and the keyword can be abbreviated</phrase>:</p>
               <eg xml:space="preserve">fn($x, $y) { $x + $y }</eg>
               <p diff="add" at="A">A zero-arity function can be written as, for example, <code nobreak="false">fn() { current-date() }</code>.</p>
               <p>
          If a function parameter is declared using a name but no type, its default type is <code nobreak="false">item()*</code>.
                  <!--<phrase diff="add" at="A">If it is bound to the context value using the notation <code>.</code>,
                  the implicit type is <code>item()</code>.</phrase>-->
               If the result type is omitted, its default result type is <code nobreak="false">item()*</code>.
          </p>
               <p>
          The parameters of an inline function expression are considered to be variables whose scope is the function body. It is a static error
          <errorref class="ST" code="0039"/> for an inline function expression to have more than one parameter with the same name.
          </p>
               <p role="xquery">An inline function
	  expression may have
	  annotations; however, no annotations are defined in XQuery 4.0 
	  for inline function
	  expressions.
                  It is a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0125"/> if an inline function expression is annotated as
	  <code nobreak="false">%public</code> or <code nobreak="false">%private</code>. An
	  implementation can define annotations, in its own namespace,
	  to support functionality beyond the scope of this
	  specification.</p>
               <p>
          The static context for the function body is inherited from the location of the inline function expression.
          </p>
               <p>
          The variables in scope for the function body include all variables representing the function parameters, as well as all variables that
          are in scope for the inline function expression.</p>
               <note>
                  <p>
            Function parameter names can mask variables that would otherwise be in scope for the function body.
          </p>
               </note>
               <p>The result of an inline function expression is a single function item
                  with the following properties (as defined in <xspecref spec="DM40" ref="function-items"/>):</p>
               <ulist>
                  <item>
                     <p>
                        <term>name</term>:
              Absent.
            </p>
                  </item>
                  <item>
                     <p diff="add" at="2023-05-25">
                        <term>identity</term>: A new function
                              identity distinct from the identity of any other function item.</p>
                     <note>
                        <p>See also <specref ref="id-function-identity"/>.</p>
                     </note>
                  </item>
                  <item>
                     <p>
                        <term>signature</term>:
              A <code nobreak="false">FunctionType</code>
              constructed from the
              <phrase role="xquery">
                           <code nobreak="false">Annotation</code>s and</phrase>
                        <code nobreak="false">SequenceType</code>s in the <code nobreak="false">InlineFunctionExpr</code>.
	      An implementation which can determine a more specific signature (for example, through use of type analysis of the function’s body) is permitted to do so.
            </p>
                  </item>
                  <item>
                     <p>
                        <term>annotations</term>: 
                              <phrase role="xquery">The annotations explicitly
                                 included in the inline function expression.</phrase>
                     </p>
                  </item>
                  <item>
                     <p>
                        <term>body</term>:
              The <code nobreak="false">FunctionBody</code> of the <code nobreak="false">InlineFunctionExpr</code>.
            </p>
                  </item>
                  <item>
                     <p diff="chg" at="2023-03-11">
                        <term>captured context</term>: the static context
                           is the static context of the inline function expression. The dynamic context has an absent
                           <termref def="dt-focus"/>, and a set of variable bindings
                           comprising the <termref def="dt-variable-values">variable values</termref> component
                           of the dynamic context of the <code nobreak="false">InlineFunctionExpr</code>.
            </p>
                  </item>
               </ulist>
               <p>The following are examples of some inline function expressions:</p>
               <ulist>
                  <item>
                     <p>This example creates a function that takes no arguments and returns a sequence of the first 6 primes:
                <eg role="parse-test" xml:space="preserve">function() as xs:integer+ { 2, 3, 5, 7, 11, 13 }</eg>
                     </p>
                  </item>
                  <item>
                     <p>This example creates a function that takes two <code nobreak="false">xs:double</code> arguments and returns their product:
                <eg role="parse-test" xml:space="preserve">fn($a as xs:double, $b as xs:double) as xs:double { $a * $b }</eg>
                     </p>
                  </item>
                  <item>
                     <p>This example creates and invokes a function that captures the value of a local variable in its scope:
                        <eg role="parse-test" xml:space="preserve">let $incrementors := (
  for $x in 1 to 10
  return function($y) as xs:integer { $x + $y }
)
return $incrementors[2](4)</eg>
                     </p>
                     <p>The result of this expression is <code nobreak="false">6</code>
                     </p>
                  </item>
               </ulist>
               <div4 id="id-focus-functions">
                  <head>Focus Functions</head>
                  <p>
                     <termdef id="dt-focus-function" term="focus function">A <term>focus function</term>
               is an inline function expression in which the function signature is implicit: the function takes
               a single argument of type <code nobreak="false">item()*</code> (that is, any value), and binds this to the 
                  context value when evaluating
               the function body, which returns a result of type <code nobreak="false">item()*</code>.</termdef>
                  </p>
                  <p>Here are some examples of focus functions:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">fn { @age }</code> - a function that expects a node as its argument, and returns
                  the <code nobreak="false">@age</code> attribute of that node.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">fn { . + 1 }</code> - a function that expects a number as its argument, and returns
                  that number plus one.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">function { `${ . }` }</code> - a function that expects a string as its argument, and prepends
                     a <code nobreak="false">"$"</code> character.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">function { head(.) + foot(.) }</code> - a function that expects a sequence of numbers
                     as its argument, and returns the sum of the first and last items in the sequence.</p>
                     </item>
                  </ulist>
                  <p>Focus functions are often useful as arguments to simple higher-order functions such as <function>fn:sort</function>.
               For example, to sort employees by salary, write <code nobreak="false">sort(//employee, (), fn { +@salary })</code>.
               (The unary plus has the effect of converting the attribute’s value to a number, for numeric sorting).</p>
                  <p>Focus functions can also be useful on the right-hand side of the <termref def="dt-sequence-arrow-operator"/>
                  and <termref def="dt-mapping-arrow-operator"/>.
               For example, <code nobreak="false">$s =&gt; tokenize() =!&gt; fn { `"{.}"` }()</code> first tokenizes the string <code nobreak="false">$s</code>,
               then wraps each token in double quotation marks.</p>
                  <p>The result of calling the <code nobreak="false">function { EXPR }</code> (or <code nobreak="false">fn { EXPR }</code>), with
                  a single argument whose value is <var>$Z</var> arguments, is obtained by evaluating <code nobreak="false">EXPR</code>
                  with a <termref def="dt-fixed-focus"/> in which the context value is <var>$Z</var>, the context position is 1 (one),
                  and the context size is 1 (one).</p>
                  <p>The expression <code nobreak="false">function { EXPR }</code> is thus formally equivalent to the expression
               <code nobreak="false">function($Z as item()*) as item()* { $Z -&gt; (EXPR) }</code>, where <code nobreak="false">$Z</code> is some variable name
               that is otherwise unused. Here <code nobreak="false">-&gt;</code> is the pipeline operator described
               in <specref ref="id-pipeline-operator"/>.</p>
                  <p>For example, the expression <code nobreak="false">every(1 to 10, fn { . gt 0 })</code> returns <code nobreak="false">true</code>.</p>
               </div4>
            </div3>
            <div3 id="id-function-identity">
               <head>Function Identity</head>
               <p>It is sometimes useful to be able to establish whether two variables refer to the same function
               or to different functions. For this purpose, every function item has an identity. Functions with the
               same identity are indistinguishable in every way; in particular, any function call with identical
               arguments will produce an identical result.</p>
               <p>In general, evaluation of an expression that returns a function item other than one that was
               present in its operands delivers a function item whose identity is unique, and thus distinct
               from any other function item. There are two exceptions to this rule:</p>
               <ulist>
                  <item>
                     <p>Evaluating a function reference such as <code nobreak="false">count#1</code> returns the same function
                  every time. Specifically, if the function name identifies a <termref def="dt-function-definition"/>
                  that is not <termref def="dt-context-dependent"/> (which is the most usual case), then all 
                     function references using this function name and arity return the same function.
                  For more details see <specref ref="id-named-function-ref"/>.</p>
                  </item>
                  <item>
                     <p>An optimizer is permitted to rewrite <xtermref spec="FO40" ref="dt-deterministic"/>
                     expressions in such a way that repeated evaluation is avoided, and this may be
                     done without consideration of function identity. For example:</p>
                     <ulist>
                        <item>
                           <p>If the expression
                           <code nobreak="false">contains(?, "e")</code> appears within the body of a <code nobreak="false">for</code>
                           clause, or if the same expression is written repeatedly in a query, then an
                           optimizer may decide to evaluate it once only, and thus return the same function
                           item each time.</p>
                        </item>
                        <item>
                           <p>Similarly, if the expression <code nobreak="false">fn($x) { $x + 1 }</code>
                           appears more than once, or is evaluated repeatedly, then it may return the same
                           function each time.</p>
                        </item>
                        <item>
                           <p>Optimizers are allowed to replace any expression with an
                           equivalent expression. For example, <code nobreak="false">count(?)</code> may be rewritten as
                           <code nobreak="false">count#1</code>. Similarly, <code nobreak="false">fn($x) { $x + 1 }</code> may be
                           rewritten as <code nobreak="false">fn($y) { $y + 1 }</code>. This may lead to different
                           expressions returning identical function items.</p>
                        </item>
                        <item>
                           <p>In principle, two function items are not identical if they
                           differ in their captured context. Optimizers, however, will often
                           be able to eliminate parts of the captured context that a function does
                           not actually use. For example, an inline function expression delivers
                           a function item whose captured context includes the values of all nonlocal
                           in-scope variables; but in practice the implementation is unlikely to retain the
                           values of such variables unless they are actually referenced.
                        </p>
                        </item>
                     </ulist>
                  </item>
               </ulist>
            </div3>
         </div2>
         <div2 id="id-path-expressions">
            <head>Path Expressions</head>
            <changes>
               <change issue="2054">
               Path expressions are extended to handle JNodes (found in trees of maps and arrays)
               as well as XNodes (found in trees representing parsed XML).
            </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-PathExpr">
                  <lhs>PathExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AbsolutePathExpr">AbsolutePathExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-RelativePathExpr">RelativePathExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-leading-lone-slash">xgc: leading-lone-slash</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-PathExpr-AbsolutePathExpr">
                  <lhs>AbsolutePathExpr</lhs>
                  <rhs>("/"  <nt def="prod-xquery40-RelativePathExpr">RelativePathExpr<!--$idref_lang_part = xquery40- --></nt>?)  |  ("//"  <nt def="prod-xquery40-RelativePathExpr">RelativePathExpr<!--$idref_lang_part = xquery40- --></nt>)</rhs>
               </prod>

               <prod id="doc-xquery40-PathExpr-RelativePathExpr">
                  <lhs>RelativePathExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-StepExpr">StepExpr<!--$idref_lang_part = xquery40- --></nt>  (("/"  |  "//")  <nt def="prod-xquery40-StepExpr">StepExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-path-expression" term="path expression">A <term>path expression</term>
            is either an <termref def="dt-absolute-path-expression"/> or a
            <termref def="dt-relative-path-expression"/>
               </termdef>
            </p>
            <p>
               <termdef id="dt-absolute-path-expression" term="absolute path expression">
            An <term>absolute path expression</term> is an instance 
            of the production <nt def="prod-xquery40-AbsolutePathExpr">AbsolutePathExpr<!--$spec = xquery40--></nt>:
            it consists of either (a) the operator <code nobreak="false">/</code> followed by zero or more 
            operands separated by <code nobreak="false">/</code> or <code nobreak="false">//</code> operators, or (b) the operator <code nobreak="false">//</code>
            followed by one or more operands separated by <code nobreak="false">/</code> or <code nobreak="false">//</code>
            operators.</termdef>
            </p>
            <p>
               <termdef id="dt-relative-path-expression" term="relative path expression">
            A <term>relative path expression</term> is a <termref def="dt-non-trivial"/>
            instance of the production <nt def="doc-xquery40-RelativePathExpr">RelativePathExpr<!--$spec = xquery40--></nt>:
            it consists of two or more operand expressions 
            separated by <code nobreak="false">/</code> or <code nobreak="false">//</code> operators.</termdef>
            </p>
            <p>
               <termdef id="dt-step" term="step">The operands of a path expression
            are conventionally referred to as <term>steps</term>.</termdef>
            </p>
            <note>
               <p>The term <term>step</term> must not be confused with
         <termref def="dt-axis-step"/>. A <term>step</term> can be any kind of
         expression, often but not necessarily an <termref def="dt-axis-step"/>,
         while an <termref def="dt-axis-step"/> can be used in any expression
         context, not necessarily as a <termref def="dt-step"/> in a path
         expression.</p>
            </note>
            <p>A path expression is typically used to locate <termref def="dt-GNode">GNodes</termref> 
            within <termref def="dt-GTree">GTrees</termref>. </p>
            <note>
               <p>Note the terminology:</p>
               <ulist>
                  <item>
                     <p>A <termref def="dt-GNode"/> is a generalized node, either an
               <termref def="dt-XNode"/> or a <termref def="dt-JNode"/>.</p>
                  </item>
                  <item>
                     <p>A <termref def="dt-GTree"/> is a generalized tree, either an
               <termref def="dt-XTree"/> or a <termref def="dt-JTree"/>.</p>
                  </item>
               </ulist>
            </note>
            <p>The following definitions are copied from the data model specification,
         for convenience:</p>
            <ulist>
               <item>
                  <p>
                     <termdef id="dt-JTree" term="JTree">A tree that is rooted at a parentless
    <termref def="dt-JNode"/> is referred to as a <term>JTree</term>.</termdef>
                  </p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-XTree" term="XTree">A tree that is rooted at a parentless
    <termref def="dt-XNode"/> is referred to as an <term>XTree</term>.</termdef>
                  </p>
               </item>
               <!--<item><p><termdef id="dt-GNode" term="GNode">The term <term>generic node</term> or <term>GNode</term>
    is a collective term for <termref def="dt-XNode">XNodes</termref> (more commonly called simply
      <termref def="dt-node">nodes</termref>) representing
    the parts of an XML document, and <termref def="dt-JNode">JNodes</termref>, 
    often used to represent the parts of a JSON document.</termdef></p></item>
         <item><p><termdef id="dt-JNode" term="JNode">A <term>JNode</term> is a kind of <termref def="dt-item"/>
      used to represent a value within the context of a tree of <termref def="dt-map">maps</termref>
      and <termref def="dt-array">arrays</termref>. A root <term>JNode</term> represents
      a map or array; a non-root <term>JNode</term> represents a <termref def="dt-member"/> of an 
      array or an <termref def="dt-entry"/> in a map.</termdef></p></item>-->
               <item>
                  <p>
                     <termdef id="dt-GTree" term="GTree">The term <term>GTree</term>
         means <termref def="dt-JTree"/> or <termref def="dt-XTree"/>.</termdef>
                  </p>
               </item>
            </ulist>
            <p>
               <termref def="dt-absolute-path-expression">Absolute path expressions</termref> 
            (those starting with an initial <code nobreak="false">/</code>
            or <code nobreak="false">//</code>), start their selection from the root GNode of a GTree;
            relative path expressions (those without a leading <code nobreak="false">/</code> or
            <code nobreak="false">//</code>) start from the <termref def="dt-context-value"/>.</p>
            <div3 id="id-absolute-path-expressions">
               <head>Absolute Path Expressions</head>
               <p>The expression consisting of <code nobreak="false">/</code> on its own
            is treated as an abbreviation for the 
            <termref def="dt-path-expression"/>
                  <code nobreak="false">/.</code>.</p>
               <p>An expression of the form <code nobreak="false">/<var>PP</var>
                  </code> (that is, a <termref def="dt-path-expression"/>
            with a leading <code nobreak="false">/</code>) is treated as an abbreviation for
	 the expression <code nobreak="false">self::gnode()/(fn:root(.) treat as (document-node()|jnode())/<var>PP</var>
                  </code>. 
            The effect of this expansion is that for every item <var>J</var> 
            in the context value <var>V</var>:</p>
               <olist>
                  <item>
                     <p>A <termref def="dt-type-error"/> occurs if <var>J</var> is not a GNode
	       <errorref class="TY" code="0020"/>.</p>
                  </item>
                  <item>
                     <p>The root GNode <var>R</var> of the GTree containing <var>J</var> is selected.</p>
                  </item>
                  <item>
                     <p>A <termref def="dt-type-error"/> occurs if <var>R</var> is neither a JNode nor 
	       a document node <errorref class="DY" code="0050"/>.</p>
                  </item>
                  <item>
                     <p>The expression that follows the leading <code nobreak="false">/</code> is evaluated with 
	       <var>R</var> as the context value.</p>
                  </item>
               </olist>
               <note>
                  <p>If the context value includes a map or array, it is <emph>not</emph>
            converted implicitly to a JNode; rather, a type error occurs.</p>
               </note>
               <p>The results of these multiple evaluations are then combined into a single sequence;
       if the result is a set of GNodes, the GNodes are delivered in document order with
       duplicates eliminated.</p>
               <note>
                  <p id="Chg-slash-note">The <code nobreak="false">/</code> character
	 can be used either as a complete expression or as the
	 beginning of a longer <termref def="dt-path-expression"/> such as
	 <code nobreak="false">/*</code>.  Also, <code role="parse-test" nobreak="false">*</code>
	 is both the multiply operator and a wildcard in path
	 expressions.  This can cause parsing difficulties when
	 <code nobreak="false">/</code> appears on the left-hand side of
	 <code nobreak="false">*</code>.  This is resolved using the <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                          href="#parse-note-leading-lone-slash"
                          xlink:type="simple"
                          xlink:show="replace"
                          xlink:actuate="onRequest">leading-lone-slash
	 </loc> constraint.  For example, <code role="parse-test" nobreak="false">/*</code> and <code role="parse-test" nobreak="false">/
	 *</code> are valid path expressions containing wildcards,
	 but <code nobreak="false">/*5</code> and <code nobreak="false">/ * 5</code> raise syntax
	 errors. Parentheses must be used when <code nobreak="false">/</code> is
	 used on the left-hand side of an operator that could be confused with a node test, as in <code role="parse-test" nobreak="false">(/) * 5</code>. Similarly, <code nobreak="false">4 + / *
	 5</code> raises a syntax error, but <code role="parse-test" nobreak="false">4 + (/) * 5</code> is a valid expression.
	 The expression <code role="parse-test" nobreak="false">4 + /</code> is also
	 valid, because <code nobreak="false">/</code> does not occur on the left-hand
	 side of the operator.</p>
                  <p>Similarly, in the expression <code role="parse-test" nobreak="false">/
	 union /*</code>, <code nobreak="false">union</code> is interpreted as an element name
	 rather than an operator. For it to be parsed as an operator,
	 the expression should be written <code role="parse-test" nobreak="false">(/)
	 union /*</code>.</p>
               </note>
               <p>An expression of the form <code nobreak="false">//<var>PP</var>
                  </code> (that is, an <termref def="dt-absolute-path-expression"/>
            with a leading <code nobreak="false">//</code>) is treated as an abbreviation for
            the expression <code nobreak="false">self::gnode()/(fn:root(.) treat as (document-node()|jnode())/descendant-or-self::gnode()/<var>PP</var>
                  </code>. 
            The effect of this expansion is that for every item <var>J</var> 
            in the context value <var>V</var>:</p>
               <olist>
                  <item>
                     <p>A <termref def="dt-type-error"/> occurs if <var>J</var> is not a GNode
               <errorref class="TY" code="0020"/>.</p>
                  </item>
                  <item>
                     <p>The root GNode <var>R</var> of the GTree containing <var>J</var> is selected.</p>
                  </item>
                  <item>
                     <p>A <termref def="dt-type-error"/> occurs if <var>R</var> is neither a JNode nor a document node
               <errorref class="DY" code="0050"/>.</p>
                  </item>
                  <item>
                     <p>The descendants of <var>R</var> are selected, along with <var>R</var> itself.</p>
                  </item>
                  <item>
                     <p>For every GNode <var>D</var> in this set of GNodes, the expression that 
               follows the leading <code nobreak="false">//</code> is evaluated with <var>D</var> as the context value.</p>
                  </item>
               </olist>
               <p>The results of these multiple evaluations are then combined into a single sequence;
            if the result is a set of GNodes, the GNodes are delivered in document order with
            duplicates eliminated.</p>
               <p>If the context value is not a sequence of GNodes, a
	 <termref def="dt-type-error">type error</termref> is
	 raised <errorref class="TY" code="0020"/>. At evaluation time, if the
	 root GNode of any item in the context value is not a document node or a JNode, a
	 <termref def="dt-type-error"/> is
	 raised <errorref class="DY" code="0050"/>.</p>
               <note>
                  <p>The descendants of an XNode do not include attribute
	 nodes. However, the rules for expanding <code nobreak="false">//</code>
            ensure that <code nobreak="false">.//@*</code> selects all attributes of all descendants</p>
               </note>
               <note>
                  <p>
                     <code nobreak="false">//</code> on its own is not a valid expression.</p>
               </note>
            </div3>
            <div3 id="id-relative-path-expressions">
               <head>Relative Path Expressions</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-RelativePathExpr">
                     <lhs>RelativePathExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-StepExpr">StepExpr<!--$idref_lang_part = xquery40- --></nt>  (("/"  |  "//")  <nt def="prod-xquery40-StepExpr">StepExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="doc-xquery40-RelativePathExpr-StepExpr">
                     <lhs>StepExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-AxisStep">AxisStep<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-RelativePathExpr-PostfixExpr">
                     <lhs>PostfixExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-RelativePathExpr-AxisStep">
                     <lhs>AxisStep</lhs>
                     <rhs>(<nt def="doc-xquery40-AbbreviatedStep">AbbreviatedStep<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FullStep">FullStep<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-Predicate">Predicate<!--$idref_lang_part = xquery40- --></nt>*</rhs>
                  </prod>
               </scrap>
               <p>
          A <termref def="dt-relative-path-expression"/> is a path expression that selects
          GNodes within a GTree by following a series of steps starting
          at the GNodes in the context value (which may be any kind of GNode,
          not necessarily the root of the tree).
          </p>
               <p>
          Each non-initial occurrence of <code nobreak="false">//</code> in a path expression is
          expanded as described in <specref ref="id-recursive-path-operator"/>, leaving a
          sequence of steps separated by <code nobreak="false">/</code>. This sequence of steps
          is then evaluated from left to right. So a path such as
          <code nobreak="false">
                     <var>E1</var>/<var>E2</var>/<var>E3</var>/<var>E4</var>
                  </code> is evaluated
          as <code nobreak="false">((<var>E1</var>/<var>E2</var>)/<var>E3</var>)/<var>E4</var>
                  </code>. 
               The semantics of a path
          expression are thus defined by the semantics of the
          binary <code nobreak="false">/</code> operator, which is defined in
          <specref ref="id-path-operator"/>.
          </p>
               <note>
                  <p>
         Although the semantics describe the evaluation of a path with
         more than two steps as proceeding from left to right, the <code nobreak="false">/</code>
         operator is in most cases associative, so evaluation from
         right to left usually delivers the same result. The cases
         where <code nobreak="false">/</code> is not associative arise when the functions
         <code nobreak="false">fn:position()</code> and <code nobreak="false">fn:last()</code> are
         used: <code nobreak="false">A/B/position()</code> delivers a sequence of
         integers from 1 to the size of <code nobreak="false">(A/B)</code>, whereas
         <code nobreak="false">A/(B/position())</code> restarts the counting at each <code nobreak="false">B</code> element.
         </p>
               </note>
               <p>The following example illustrates the use of a relative path expressions
               to select within an XTree.
            It is assumed that the context value is a single XNode,
            referred to as the context node.</p>
               <example>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">child::div1/child::para</code>
                        </p>
                        <p>Selects the
	     <code nobreak="false">para</code> element children of the <code nobreak="false">div1</code>
	     element children of the context node; that is, the
	     <code nobreak="false">para</code> element grandchildren of the context node
	     that have <code nobreak="false">div1</code> parents.</p>
                     </item>
                  </ulist>
               </example>
               <note>
                  <p>Since each step in a path provides context GNodes for the following step, 
                  in effect, only the last step in a path is allowed to return a sequence of non-GNodes.</p>
               </note>
            </div3>
            <div3 id="id-path-operator">
               <head>Path Operator (<code nobreak="false">/</code>)</head>
               <p>The path operator <code nobreak="false">/</code> is primarily used for 
                  locating GNodes within GTrees. The value of the left-hand operand
                  may include maps and arrays; such items are implicitly converted to JNodes
                  as if by a call on the <function>fn:jtree</function> function.
                  After this conversion, the left-hand operand must return 
                  a sequence of GNodes. The result of the operator is either a sequence of GNodes
                  (in document order, with no duplicates), or a sequence of non-GNodes.</p>
               <p>The operation <code nobreak="false">
                     <var>E1</var>/<var>E2</var>
                  </code> is evaluated as follows: Expression <var>E1</var> 
                  is evaluated. Any maps or arrays in the result are converted to JNodes
                  by applying the <function>fn:jtree</function> function. If the result is not a 
                  (possibly empty) sequence <var>S</var> of GNodes, 
                  a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0019"/>. Each GNode in <var>S</var> then serves in turn to provide an inner focus 
                  (the GNode as the context value, its position in <var>S</var> as the context 
                  position, the length of <code nobreak="false">S</code> as the context size) for an evaluation 
                  of <var>E2</var>, as described in  <specref ref="eval_context"/>. The sequences resulting from all the evaluations of <var>E2</var> 
                  are combined as follows:</p>
               <olist>
                  <item>
                     <p>If every evaluation of <var>E2</var> returns a (possibly empty) sequence of GNodes, 
                        these sequences are combined, and duplicate GNodes are eliminated based on GNode identity.
                        The resulting GNode sequence is returned in <termref def="dt-document-order">document order</termref>.
                     </p>
                  </item>
                  <item>
                     <p>If every evaluation of <var>E2</var> returns a (possibly empty) 
                        sequence of non-GNodes, these sequences are concatenated, in order, and returned.
                        The returned sequence preserves the orderings within and among the subsequences 
                        generated by the evaluations of <var>E2</var>.
                     </p>
                     <note>
                        <p>The use of <termref def="dt-path-expression">path expressions</termref> 
                        to select values other than GNodes is for
                     backwards compatibility. Generally it is preferable to use the simple mapping
                     operator <code nobreak="false">!</code> for this purpose. For example, write <code nobreak="false">$nodes!node-name()</code>
                     in preference to <code nobreak="false">$nodes/node-name()</code>.</p>
                     </note>
                  </item>
                  <item>
                     <p>If the multiple evaluations of <var>E2</var> return at least one GNode and at least one non-GNode, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0018"/>.</p>
                  </item>
               </olist>
               <note>
                  <p>The semantics of the path operator can also be defined using the simple 
                     map operator (<code nobreak="false">!</code>) as follows (the function
                     <code nobreak="false">fn:distinct-ordered-nodes($R)</code> has the effect of 
                     eliminating duplicates and sorting nodes into document order):</p>
                  <eg xml:space="preserve">let $R := E1 ! E2
return if (every $r in $R satisfies $r instance of gnode())
       then (fn:distinct-ordered-nodes($R))
       else if (every $r in $R satisfies not($r instance of gnode()))
       then $R
       else error()</eg>
                  <p>For a table comparing the step operator to the map operator, see <specref ref="id-map-operator"/>.</p>
               </note>
            </div3>
            <div3 id="id-recursive-path-operator">
               <head>Recursive Path Operator (<code nobreak="false">//</code>)</head>
               <p>When <code nobreak="false">//</code> is used as an infix operator, it can be treated as an abbreviation
           for <code nobreak="false">/descendant-or-self::gnode()/</code>.</p>
               <p>In simple cases, an expression such as <code nobreak="false">$x//y</code> is equivalent to
            <code nobreak="false">$x/descendant::y</code>. But in some cases the semantics are more complex, for example:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">$x//@a</code> expands to <code nobreak="false">$x/descendant-or-self::gnode()/attribute::a</code>, which selects
               all attributes having <code nobreak="false">$x</code> as an ancestor.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">$x//y[1]</code> expands to <code nobreak="false">$x/descendant-or-self::gnode()/child::y[1]</code>,
               which selects every descendant element of <code nobreak="false">$x</code> named <code nobreak="false">y</code> that is the 
                     first child of its parent. This is <emph>not</emph> the same as <code nobreak="false">($x//y)[1]</code>, which selects
               the first descendant of <code nobreak="false">$x</code> that is named <code nobreak="false">y</code>.</p>
                  </item>
               </ulist>
               <p>The <code nobreak="false">//</code> operator can be used both with XNodes and with JNodes: the same expansion applies
            in both cases. For example, if <code nobreak="false">$x</code> is the array:</p>
               <eg xml:space="preserve">[ {"a":10, "b":11}, [ {"a":20, "b":21} ] ]</eg>
               <p>then <code nobreak="false">$x//b</code> returns two JNodes whose contents are <code nobreak="false">11</code> and <code nobreak="false">21</code>
            respectively.</p>
               <p>It is valid, but rarely useful, to use the <code nobreak="false">//</code> operator in conjunction with an axis other than
            <code nobreak="false">child</code> or <code nobreak="false">attribute</code>. For example, <code nobreak="false">$x//following-sibling::y</code>
            expands to <code nobreak="false">$x/descendant-or-self::gnode()/following-sibling::y</code>, which selects every <code nobreak="false">y</code>
               descendant of <code nobreak="false">$x</code> that is not the first child of its parent, as well as the following siblings
               of <code nobreak="false">$x</code> itself.</p>
               <p>It is also valid to follow <code nobreak="false">//</code> with an expression other than an axis step. For example,
            <code nobreak="false">distinct-values($x//node-name())</code> has the same effect as 
               <code nobreak="false">$x/descendant-or-self::gnode() =!&gt; node-name() =&gt; distinct-values()</code>
               </p>
               <p>The effect of <code nobreak="false">//</code> at the start of an expression is explained in
               <specref ref="id-absolute-path-expressions"/>.</p>
            </div3>
            <div3 id="id-axis-steps">
               <head>Axis Steps</head>
               <scrap headstyle="show">
                  <head/>
                  <prod id="doc-xquery40-AxisStep">
                     <lhs>AxisStep</lhs>
                     <rhs>(<nt def="doc-xquery40-AbbreviatedStep">AbbreviatedStep<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FullStep">FullStep<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-Predicate">Predicate<!--$idref_lang_part = xquery40- --></nt>*</rhs>
                  </prod>

                  <prod id="doc-xquery40-AxisStep-AbbreviatedStep">
                     <lhs>AbbreviatedStep</lhs>
                     <rhs>".."  |  ("@"  <nt def="doc-xquery40-NodeTest">NodeTest<!--$idref_lang_part = xquery40- --></nt>)  |  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AxisStep-FullStep">
                     <lhs>FullStep</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Axis">Axis<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="doc-xquery40-NodeTest">NodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AxisStep-Axis">
                     <lhs>Axis</lhs>
                     <rhs>("ancestor"  |  "ancestor-or-self"  |  "attribute"  |  "child"  |  "descendant"  |  "descendant-or-self"  |  "following"  |  "following-or-self"  |  "following-sibling"  |  "following-sibling-or-self"  |  "parent"  |  "preceding"  |  "preceding-or-self"  |  "preceding-sibling"  |  "preceding-sibling-or-self"  |  "self")  "::"</rhs>
                  </prod>

                  <prod id="doc-xquery40-AxisStep-NodeTest">
                     <lhs>NodeTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-UnionNodeTest">UnionNodeTest<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AxisStep-Predicate">
                     <lhs>Predicate</lhs>
                     <rhs>"["  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "]"</rhs>
                  </prod>
               </scrap>
               <p>
                  <termdef term="axis step" id="dt-axis-step">An <term>axis step</term> is an instance of the production
                  <nt def="doc-xquery40-AxisStep">AxisStep<!--$spec = xquery40--></nt>: it is an expression that 
                  returns a sequence of GNodes that are 
                  reachable from a starting GNode via a specified axis. An axis step has three parts: an
		<term>axis</term>, which defines the direction of
		movement for the step, a <termref def="dt-node-test">node test</termref>,
		which selects GNodes based on their properties, and zero or more predicates which are used
               to filter the results.</termdef>
               </p>
               <note>
                  <p>An <termref def="dt-axis-step"/> is an expression in its own right.
               While axis steps are often used as the operands of 
               <termref def="dt-path-expression">path expressions</termref>,
            they can also appear in other contexts (without a <code nobreak="false">/</code> or <code nobreak="false">//</code>
            operator); equally, the operands of a path expression can be any expression,
            not restricted to an <termref def="dt-axis-step"/>.</p>
               </note>
               <p>If the context value for an <termref def="dt-axis-step"/> includes a map or array, this is implicitly
               converted to a JNode as if by applying the <function>fn:jtree</function> function.
               If, after this conversion, the sequence contains a value that is not a GNode, 
               a <termref def="dt-type-error">type error</termref> is
		         raised <errorref class="TY" code="0020"/>. The result of evaluating the axis step
               is a sequence of zero or more GNodes.</p>
               <p>The <termref def="dt-axis-step"/>
                  <code nobreak="false">S</code> is equivalent to <code nobreak="false">./S</code>.
               Thus, if the context value is a sequence containing multiple GNodes,
               the semantics of a <termref def="dt-axis-step"/> are equivalent to a <termref def="dt-path-expression"/>
               in which the step is always applied to a single GNode. The following
               description therefore explains the semantics for the case where
               the context value is a single GNode, called the <term>origin</term>.</p>
               <note>
                  <p>The equivalence of a <termref def="dt-axis-step"/>
                     <code nobreak="false">S</code> to the
            <termref def="dt-path-expression"/>
                     <code nobreak="false">./S</code> means that 
            the resulting GNode sequence is returned in <termref def="dt-document-order">document
	         order</termref>.</p>
               </note>
               <!--<p>An axis step may be either a <term>forward
		step</term> or a <term>reverse step</term>, followed
		by zero or more <termref def="dt-predicate">predicates</termref>.</p>-->
               <p>In the <term>abbreviated syntax</term> for a step, the axis can
		be omitted and other shorthand notations can be used as described in
		<specref ref="abbrev"/>.</p>
               <p>The unabbreviated syntax for an axis step consists of the axis name
		and node test separated by a double colon. The result of the step consists of the GNodes
		reachable from the origin via the specified axis that match the node test. For example, the
		step <code role="parse-test" nobreak="false">child::para</code> selects the <code nobreak="false">para</code> element children of the origin XNode: 
               <code nobreak="false">child</code> is the name of the axis, and <code nobreak="false">para</code> is the name of the element nodes 
               to be selected on this axis. The available axes are described in <specref ref="axes"/>. The
		available node tests are described in <specref ref="node-tests"/>. Examples of
		steps are provided in <specref ref="unabbrev"/> and <specref ref="abbrev"/>.</p>
               <div4 id="axes">
                  <head>Axes</head>
                  <changes>
                     <change issue="1519" PR="1532" date="2024-10-29">
                     Four new axes have been defined: <code nobreak="false">preceding-or-self</code>, <code nobreak="false">preceding-sibling-or-self</code>,
                     <code nobreak="false">following-or-self</code>, and <code nobreak="false">following-sibling-or-self</code>.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-Axis">
                        <lhs>Axis</lhs>
                        <rhs>("ancestor"  |  "ancestor-or-self"  |  "attribute"  |  "child"  |  "descendant"  |  "descendant-or-self"  |  "following"  |  "following-or-self"  |  "following-sibling"  |  "following-sibling-or-self"  |  "parent"  |  "preceding"  |  "preceding-or-self"  |  "preceding-sibling"  |  "preceding-sibling-or-self"  |  "self")  "::"</rhs>
                     </prod>
                  </scrap>
                  <p>An axis is essentially a function that takes a GNode (the origin)
               as input, and delivers a sequence of GNodes (always from within the same
               GTree as the origin) as its result.</p>
                  <p role="xquery">XQuery supports the following axes:</p>
                  <ulist>
                     <item>
                        <p>The <code nobreak="false">child</code> axis
				contains the children of the origin.</p>
                        <p>If the origin is an XNode, these are the XNodes returned by the
				<xspecref spec="DM40" ref="dm-children"/> accessor.
                                </p>
                        <note>
                           <p>In an XTree, only document nodes and element
                        nodes have children. If the origin is any
                         other kind of XNode, or if the origin is an empty
                         document or element node, then the child
                         axis returns the empty sequence.  The
                         children of a document node or element node may be
                         element, processing instruction, comment, or text
                         nodes.  Attribute, namespace, and
                         document nodes can never appear as children.</p>
                        </note>
                        <p>If the origin is a JNode, these are the JNodes returned
                     by the <xtermref spec="DM40" ref="dt-j-children"/> accessor.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">descendant</code>
			 axis is defined as the transitive closure of
			 the child axis; it contains the descendants
			 of the origin (the children, the children of the children, and so on).</p>
                        <p>More formally, <code nobreak="false">$node/descendant::gnode()</code> delivers the result
                     of <code nobreak="false">fn:transitive-closure($node, fn { child::gnode() })</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">descendant-or-self</code> axis contains the origin and the descendants 
                        of the origin.</p>
                        <p>More formally, <code nobreak="false">$node/descendant-or-self::gnode()</code> delivers the result
                     of <code nobreak="false">$node/(. | descendant::gnode())</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">parent</code> axis returns the parent of the origin.</p>
                        <p>If the origin is an XNode, this is the result of the 
                        <xspecref spec="DM40" ref="dm-parent"/> accessor.</p>
                        <p>If the origin is a JNode, this is the value of the
                        <term>·jparent·</term> property of the origin.</p>
                        <p>If the GNode has no parent, the axis returns the empty sequence.</p>
                        <note>
                           <p>An attribute node may have an element node as its parent, 
                           even though the attribute node is not a child of the element node.</p>
                        </note>
                     </item>
                     <item>
                        <p>The <code nobreak="false">ancestor</code> axis is
                        defined as the transitive closure of the parent axis; it
                        contains the ancestors of the origin (the parent, the
                        parent of the parent, and so on).</p>
                        <p>More formally, <code nobreak="false">$node/ancestor::gnode()</code> delivers the result
                     of <code nobreak="false">fn:transitive-closure($node, fn { parent::gnode() })</code>.</p>
                        <note>
                           <p>The ancestor axis includes the root GNode of the
                           GTree in which the origin is found, unless the origin is 
                           itself the root GNode.</p>
                        </note>
                     </item>
                     <item>
                        <p>The <code nobreak="false">ancestor-or-self</code> axis contains the origin and the ancestors of the origin;
				            thus, the ancestor-or-self axis will always include the root.</p>
                        <p>More formally, <code nobreak="false">$node/ancestor-or-self::gnode()</code> delivers the result
                     of <code nobreak="false">$node/(. | ancestor::gnode())</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">following-sibling</code>
			 axis returns the origin’s following
			 siblings, that is, those children of the origin’s parent that occur after the origin in <termref def="dt-document-order">document order</termref>. If the origin
			 is an attribute or namespace node, the
			 <code nobreak="false">following-sibling</code> axis is
			 empty.</p>
                        <p>More formally, <code nobreak="false">$node/following-sibling::gnode()</code> delivers the result
                     of <code nobreak="false">fn:siblings($node)[. &gt;&gt; $node])</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">following-sibling-or-self</code> axis contains the origin,
                     together with the contents of the <code nobreak="false">following-sibling</code> axis.</p>
                        <p>More formally, <code nobreak="false">$node/following-sibling-or-self::gnode()</code> delivers the result
                     of <code nobreak="false">fn:siblings($node)[not(. &lt;&lt; $node)]</code>
                        </p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">preceding-sibling</code>
			 axis returns the origin’s preceding
			 siblings, that is, those children of the origin’s parent that occur before the context
			 node in <termref def="dt-document-order">document order</termref>. If the origin
			 is an attribute or namespace node, the
			 <code nobreak="false">preceding-sibling</code> axis is
			 empty.</p>
                        <p>More formally, <code nobreak="false">$node/preceding-sibling::gnode()</code> delivers the result
                     of <code nobreak="false">fn:siblings($node)[. &lt;&lt; $node]</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">preceding-sibling-or-self</code> axis contains the origin,
                     together with the contents of the <code nobreak="false">preceding-sibling</code> axis.</p>
                        <p>More formally, <code nobreak="false">$node/preceding-sibling-or-self::gnode()</code> delivers the result
                     of <code nobreak="false">fn:siblings($node)[not(. &gt;&gt; $node)</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">following</code> axis
				contains all 
				descendants of the root of the GTree in
				which the origin is found, are
				not descendants of the origin,
				and occur after the origin in
				<termref def="dt-document-order">document order</termref>.
                     </p>
                        <p>More formally, <code nobreak="false">$node/following::gnode()</code> delivers the result
                     of <code nobreak="false">$node/ancestor-or-self::gnode()/following-sibling::gnode()/descendant-or-self::gnode()</code>
                        </p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">following-or-self</code> axis contains the origin,
                     together with the contents of the <code nobreak="false">following</code> axis.</p>
                        <p>More formally, <code nobreak="false">$node/following-or-self::gnode()</code> delivers the result
                     of <code nobreak="false">$node/(. | following::gnode())</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">preceding</code> axis
				returns all 
				descendants of the root of the GTree in
				which the origin is found, are
				not ancestors of the origin, and
				occur before the origin in
				<termref def="dt-document-order">document order</termref>.
                     </p>
                        <p>More formally, <code nobreak="false">$node/preceding::gnode()</code> delivers the result
                     of <code nobreak="false">$node/ancestor-or-self::gnode()/preceding-sibling::gnode()/descendant-or-self::gnode()</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">preceding-or-self</code> axis returns the origin,
                     together with the contents of the <code nobreak="false">preceding</code> axis.</p>
                        <p>More formally, <code nobreak="false">$node/preceding-or-self::gnode()</code> delivers the result
                     of <code nobreak="false">$node/(. | preceding::gnode())</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">attribute</code> axis is defined only for XNodes.
			 It returns the attributes of the origin,
			 which are the nodes returned by the
			 <phrase diff="chg" at="B">
                              <xspecref spec="DM40" ref="dm-attributes"/>
                           </phrase>; the axis will be
			 empty unless the context node is an
			 element.</p>
                        <p>If the <code nobreak="false">attribute</code> axis is applied to a JNode,
                     a type error <errorref class="TY" code="0004"/> is raised.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">self</code> axis contains just the origin itself.</p>
                        <p>The <code nobreak="false">self</code> axis is primarily useful when testing whether the origin
                     satisfies particular conditions, for example <code nobreak="false">if ($x[self::chapter])</code>.</p>
                        <p>More formally, <code nobreak="false">$node/self::gnode()</code> delivers the result
                     of <code nobreak="false">$node</code>.</p>
                     </item>
                  </ulist>
                  <p>Axes can be categorized as <term>forward axes</term> and
		  <term>reverse axes</term>. An axis that only ever contains the origin or
		  nodes that are after the context node in <termref def="dt-document-order">document order</termref> is a forward axis. An
		  axis that only ever contains the context node or nodes that are before the
		  context node in <termref def="dt-document-order">document order</termref> is a reverse axis.</p>
                  <p>The <code nobreak="false">parent</code>, <code nobreak="false">ancestor</code>, <code nobreak="false">ancestor-or-self</code>, 
                  <code nobreak="false">preceding</code>, <code nobreak="false">preceding-or-self</code>, 
                  <code nobreak="false">preceding-sibling</code>, and <code nobreak="false">preceding-sibling-or-self</code> axes 
                  are reverse axes; all other axes are forward axes.</p>
                  <p>The <code nobreak="false">ancestor</code>, <code nobreak="false">descendant</code>, 
                  <code nobreak="false">following</code>, <code nobreak="false">preceding</code> and <code nobreak="false">self</code> axes partition a GTree (ignoring attribute  nodes):
		  they do not overlap and together they contain all the GNodes in the
		  GTree.</p>
                  <p>
                     <termdef id="dt-principal-node-kind" term="principal node kind">Every axis has a <term>principal node kind</term>. If an axis can
		  contain elements, then the principal node kind is element; otherwise, it is the
		  kind of nodes that the axis can contain.</termdef> Thus:</p>
                  <ulist>
                     <item>
                        <p>For the attribute axis, the principal node kind is
				attribute.</p>
                     </item>
                     <item>
                        <p>For all other axes, the principal node kind is element.</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="node-tests">
                  <head>Node Tests</head>
                  <changes>
                     <change issue="296" PR="1181" date="2024-04-30">
                     If the default namespace for elements and types has the special value <code nobreak="false">##any</code>,
                     then an unprefixed name in a <code nobreak="false">NameTest</code> acts as a wildcard, matching
                     names in any namespace or none.
                  </change>
                  </changes>
                  <p>
                     <termdef id="dt-node-test" term="node test">A <term>node test</term> is a condition 
                     on the properties of a <termref def="dt-GNode"/>. 
      A node test determines which GNodes returned by an axis are selected by a <termref def="dt-step">step</termref>.</termdef>
                  </p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-NodeTest">
                        <lhs>NodeTest</lhs>
                        <rhs>
                           <nt def="prod-xquery40-UnionNodeTest">UnionNodeTest<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-NodeTest-UnionNodeTest">
                        <lhs>UnionNodeTest</lhs>
                        <rhs>"("  (<nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-NodeTest-SimpleNodeTest">
                        <lhs>SimpleNodeTest</lhs>
                        <rhs>
                           <nt def="prod-xquery40-TypeTest">TypeTest<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Selector">Selector<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-NodeTest-TypeTest">
                        <lhs>TypeTest</lhs>
                        <rhs>
                           <nt def="prod-xquery40-GNodeType">GNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-XNodeType">XNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-JNodeType">JNodeType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-NodeTest-Selector">
                        <lhs>Selector</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>  |  ("get"  "("  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  ")")</rhs>
                     </prod>

                     <prod id="doc-xquery40-NodeTest-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-NodeTest-Wildcard">
                        <lhs>Wildcard</lhs>
                        <rhs>"*"<br/>|  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":*")<br/>|  ("*:"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>)<br/>|  (<nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  "*")</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-NodeTest-ExprSingle">
                        <lhs>ExprSingle</lhs>
                        <rhs>
                           <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>
                  </scrap>
                  <p>Node tests fall into three categories:</p>
                  <ulist>
                     <item>
                        <p>Type tests, which test the type of the GNode;</p>
                     </item>
                     <item>
                        <p>Selectors, which act as keys used to identify the GNode
                     among its siblings (in the case of XNodes, this is the node name);</p>
                     </item>
                     <item>
                        <p>Union node tests, which provide multiple conditions: a GNode satisfies
                  the union node test if it satisfies any of its operand node tests.</p>
                     </item>
                  </ulist>
                  <p diff="add" at="2022-12-13">A <nt def="prod-xquery40-UnionNodeTest">UnionNodeTest<!--$spec = xquery40--></nt> matches a node <var>N</var>
                  if at least one of the constituent <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$spec = xquery40--></nt>s matches <var>N</var>.</p>
                  <p diff="add" at="2022-12-13">For example, <code nobreak="false">(div1|div2|div3)</code> matches a node named <code nobreak="false">div1</code>, <code nobreak="false">div2</code>, or <code nobreak="false">div3</code>
                  </p>
                  <p>The semantics of selectors varies between XNodes and JNodes, so the two
               cases are described separately.</p>
               </div4>
               <div4 id="id-selectors-for-xnodes">
                  <head>Selectors for XNodes</head>
                  <p>This section describes the semantics of a name test in the case
               where the origin is an XNode.</p>
                  <p>
                     <termdef id="dt-name-test" term="name test">A node test that consists only of an EQName or a
		  Wildcard is called a <term>name test</term>.</termdef>
                  </p>
                  <p>A node test written as an NCName is expanded as follows:</p>
                  <ulist>
                     <item>
                        <p>If the principal node kind of the axis step is <code nobreak="false">element</code>, 
                  using the <termref def="dt-element-name-matching-rule"/>.</p>
                        <note>
                           <p>If the <termref def="dt-default-namespace-elements-and-types"/> has the
                     special value <code nobreak="false">"##any</code>, the result of the expanding an unprefixed name
                  <var>NN</var> is the wildcard <code nobreak="false">*:<var>NN</var>
                              </code>.</p>
                        </note>
                     </item>
                     <item>
                        <p>Otherwise, using the <termref def="dt-no-namespace-rule"/>.</p>
                     </item>
                  </ulist>
                  <p>If the expanded node test is an <termref def="dt-expanded-qname"/>
                     <var>Q</var>, then it
               matches a node <var>N</var> if and only if the <term>kind</term> of
                  node <var>N</var> is the <termref def="dt-principal-node-kind">principal node kind</termref> for the step axis and the
		  <termref def="dt-expanded-qname">expanded QName</termref> of the node is equal (as defined by the <code nobreak="false">eq</code> operator) to <var>Q</var>. For
		  example, <code role="parse-test" nobreak="false">child::para</code>
		  selects the <code nobreak="false">para</code> element children of
		  the context node; if the context node has no
		  <code nobreak="false">para</code> children, it selects an empty set
		  of nodes. <code role="parse-test" nobreak="false">attribute::abc:href</code> selects
		  the attribute of the context node with the QName
		  <code nobreak="false">abc:href</code>; if the context node has no
		  such attribute, it selects an empty set of
		  nodes.</p>
                  <note>
                     <p>A name test is not satisfied by an element node whose name does not match the <termref def="dt-expanded-qname">expanded QName</termref> of the name test, even if it is in a <termref def="dt-substitution-group">substitution group</termref> whose head is the named element.</p>
                  </note>
                  <p>Wildcard node tests are interpreted as follows:</p>
                  <ulist>
                     <item>
                        <p>The node test <code nobreak="false">*</code> is true for any node of the
		  <termref def="dt-principal-node-kind">principal node
		  kind</termref> of the step axis. For example, <code role="parse-test" nobreak="false">child::*</code> will select all element
		  children of the context node, and <code role="parse-test" nobreak="false">attribute::*</code> will select all
		  attributes of the context node.</p>
                     </item>
                     <item>
                        <p>A node test can have the form
		  <code role="parse-test" nobreak="false">NCName:*</code>. In this case, the prefix is
		  expanded in the same way as with a <termref def="dt-qname">lexical QName</termref>, using the
		  <termref def="dt-static-namespaces">statically known
		  namespaces</termref> in the <termref def="dt-static-context">static context</termref>. If
		  the prefix is not found in the statically known namespaces,
		  a <termref def="dt-static-error">static
		  error</termref> is raised <errorref class="ST" code="0081"/>.
		  The node test is true for any node of the <termref def="dt-principal-node-kind">principal
		  node kind</termref> of the step axis whose <termref def="dt-expanded-qname">expanded QName</termref> has the namespace URI
		  to which the prefix is bound, regardless of the
		  local part of the name.</p>
                     </item>
                     <item>
                        <p>A node test can contain a <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$spec = xquery40--></nt>, for example
		  <code role="parse-test" nobreak="false">Q{http://example.com/msg}*</code>. Such a node test is true for any node of the principal 
                  node kind of the step axis whose <termref def="dt-expanded-qname"/> has the namespace URI specified in 
                  the <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$spec = xquery40--></nt>, regardless of the local part of the name.</p>
                     </item>
                     <item>
                        <p>A node test can also
		  have the form <code role="parse-test" nobreak="false">*:NCName</code>. In this case,
		  the node test is true for any node of the <termref def="dt-principal-node-kind">principal
		  node kind</termref> of the step axis whose local name matches the given NCName,
		  regardless of its namespace or lack of a namespace.</p>
                     </item>
                  </ulist>
                  <p>A selector can also take the form <code nobreak="false">get(<var>E</var>)</code>
                  where <var>E</var> is an <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt>.
               The contained expression <var>E</var> is evaluated with an
                  <xtermref ref="dt-absent" spec="DM40"/>
                     <termref def="dt-focus"/>. 
                  An XNode satisfies the selector if its node kind is the principal
                  node kind of the axis and its node name
                  is equal to one of the values (necessarily an <code nobreak="false">xs:QName</code>)
                  present in the atomized value of the selector expression.</p>
                  <p>That is, if the context item is an XNode, then 
                  <code nobreak="false">
                        <var>Axis</var>::get(<var>E</var>)</code> returns the result
               of the expression:</p>
                  <eg xml:space="preserve">let $selector := fn(){ data(<var>E</var>) }()
return <var>Axis</var>::*[some($selector, atomic-equal(?, node-name()))]</eg>
                  <note>
                     <p>The purpose of evaluating <var>E</var> within the body of
                  an anonymous inline function is to ensure that it is evaluated
                  with an absent focus.</p>
                     <p>It is not an error if the atomized value of <var>E</var>
               includes atomic items that are not <code nobreak="false">xs:QName</code> values:
               such values are effectively ignored.</p>
                  </note>
                  <note>
                     <p>Unnamed nodes (such as text nodes) will never be selected</p>
                  </note>
                  <note>
                     <p>The result is in document order. The order of items in
               the result of the selector expression is immaterial.</p>
                  </note>
                  <p>For example, <code nobreak="false">child::get((#body, #x:body))</code> selects
               all child elements whose name is one of the QName values <code nobreak="false">body</code>
               or <code nobreak="false">x:body</code>. Note that the evaluation of QName literals
               is not sensitive to the default namespace for elements and types.</p>
                  <p>A further example: <code nobreak="false">descendant::(get(#para) | text())</code> returns
               all descendants of the context node that are either elements named
               <code nobreak="false">para</code> (in no namespace) or text nodes; the results are in document order.</p>
               </div4>
               <div4 id="id-selectors-for-JNodes">
                  <head>Selectors for JNodes</head>
                  <p>When the origin is a JNode, the selector filters the JNodes returned
               by the axis according to the JNode's <term>·jkey·</term> property.
               In the case of a JNode that wraps an entry in a map, this can be any
               atomic item; for a JNode that wraps a member of an array, it will
               be a non-negative integer.</p>
                  <p>If the selector takes the form <code nobreak="false">*</code>, then it matches
               every JNode (including one whose <term>·jkey·</term> property
               is absent).</p>
                  <p>If the selector takes the form of an <code nobreak="false">NCName</code>, then it matches
               every JNode whose <term>·jkey·</term> property is an atomic item
                  (necessarily an <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>
                  or <code nobreak="false">xs:untypedAtomic</code> value) that is equal to this <code nobreak="false">NCName</code>
                  under the rules of the <function>fn:atomic-equal</function> function.</p>
                  <p>If the selector takes the form of any other <code nobreak="false">EQName</code> or wildcard,
               then it matches every JNode whose <term>·jkey·</term> property is a matching 
                  <code nobreak="false">xs:QName</code>, using the same rules as for wildcards in XNode steps
               (see <specref ref="id-selectors-for-xnodes"/>).</p>
                  <p>If the selector takes the form <code nobreak="false">get(<var>E</var>)</code>,
                  where <var>E</var> is an <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt>,
               the contained expression <var>E</var> is evaluated with an
                  <xtermref ref="dt-absent" spec="DM40"/>
                     <termref def="dt-focus"/>. 
                  A JNode satisfies the selector if the value of its 
                  <term>·jkey·</term> property is equal to one of the values
                  present in the atomized value of the selector expression <var>E</var>, under the rules
                  of the <function>atomic-equal</function> function.</p>
                  <p>That is, if the context item is a JNode, then 
                  <code nobreak="false">
                        <var>Axis</var>::get(<var>E</var>)</code> returns the result
               of the expression:</p>
                  <eg xml:space="preserve">let $selector := fn() { data(&lt;var&gt;E&lt;/var&gt;) }()
return &lt;var&gt;Axis&lt;/var&gt;::*[some($selector, atomic-equal(?, jkey()))]
</eg>
                  <note>
                     <p>The purpose of evaluating <var>E</var> within the body of
                  an anonymous inline function is to ensure that it is evaluated
                  with an absent focus.</p>
                     <p>It is not an error if the atomized value of <var>E</var>
               includes atomic items that select nothing: such values are effectively ignored.
               This is true both for maps and arrays.</p>
                  </note>
                  <note>
                     <p>The result is in document order. The order of items in
               the result of the selector expression is immaterial.</p>
                  </note>
                  <note>
                     <p>A performant implementation might reasonably be expected,
               at least in the case where the value of the selector is a single
               atomic item, to select an entry in a map or a member in an array
               in constant time.</p>
                  </note>
                  <p>For example:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">child::code</code> selects
               an entry in a map whose key is the string <code nobreak="false">"code"</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">child::get("date of birth")</code> selects
               an entry in a map whose key is the string <code nobreak="false">"date of birth"</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">child::get(3)</code> selects the third member
                  of an array</p>
                        <note>
                           <p>The same result can be achieved using the expression <code nobreak="false">child::*[3]</code>.</p>
                        </note>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">child::get(1 to 3)</code> selects the first three members
                  of an array, in document order.</p>
                        <note>
                           <p>
                              <code nobreak="false">child::get((3, 2, 1))</code> also returns the first three
                  members in document order.</p>
                        </note>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">child::get(current-date())</code>
               selects an entry in a map whose key is an <code nobreak="false">xs:date</code> value
               equal to the current date.</p>
                     </item>
                  </ulist>
                  <p>All the above expressions return a sequence of JNodes. If the containing
               expression expects atomic items, then the JNodes are automatically atomized.</p>
               </div4>
               <div4 id="id-type-tests">
                  <head>Type Tests</head>
                  <p>A type test is a node test that selects JNodes or XNodes based on their type.</p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-TypeTest">
                        <lhs>TypeTest</lhs>
                        <rhs>
                           <nt def="prod-xquery40-GNodeType">GNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-XNodeType">XNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-JNodeType">JNodeType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-GNodeType">
                        <lhs>GNodeType</lhs>
                        <rhs>"gnode"  "("  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-XNodeType">
                        <lhs>XNodeType</lhs>
                        <rhs>
                           <nt def="prod-xquery40-DocumentNodeType">DocumentNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-ElementNodeType">ElementNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="doc-xquery40-AttributeNodeType">AttributeNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-SchemaElementNodeType">SchemaElementNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-SchemaAttributeNodeType">SchemaAttributeNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-ProcessingInstructionNodeType">ProcessingInstructionNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-CommentNodeType">CommentNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TextNodeType">TextNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-NamespaceNodeType">NamespaceNodeType<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-AnyXNodeType">AnyXNodeType<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-DocumentNodeType">
                        <lhs>DocumentNodeType</lhs>
                        <rhs>"document-node"  "("  (<nt def="prod-xquery40-ElementNodeType">ElementNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SchemaElementNodeType">SchemaElementNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-ElementNodeType">
                        <lhs>ElementNodeType</lhs>
                        <rhs>"element"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  "?"?)?)?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-SchemaElementNodeType">
                        <lhs>SchemaElementNodeType</lhs>
                        <rhs>"schema-element"  "("  <nt def="prod-xquery40-ElementName">ElementName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-NameTestUnion">
                        <lhs>NameTestUnion</lhs>
                        <rhs>(<nt def="prod-xquery40-NameTest">NameTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-NameTest">
                        <lhs>NameTest</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-Wildcard">
                        <lhs>Wildcard</lhs>
                        <rhs>"*"<br/>|  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":*")<br/>|  ("*:"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>)<br/>|  (<nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  "*")</rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-AttributeNodeType">
                        <lhs>AttributeNodeType</lhs>
                        <rhs>"attribute"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-SchemaAttributeNodeType">
                        <lhs>SchemaAttributeNodeType</lhs>
                        <rhs>"schema-attribute"  "("  <nt def="prod-xquery40-AttributeName">AttributeName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-ProcessingInstructionNodeType">
                        <lhs>ProcessingInstructionNodeType</lhs>
                        <rhs>"processing-instruction"  "("  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-StringLiteral">
                        <lhs>StringLiteral</lhs>
                        <rhs>
                           <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#ws-explicit">ws: explicit</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-CommentNodeType">
                        <lhs>CommentNodeType</lhs>
                        <rhs>"comment"  "("  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-TextNodeType">
                        <lhs>TextNodeType</lhs>
                        <rhs>"text"  "("  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-NamespaceNodeType">
                        <lhs>NamespaceNodeType</lhs>
                        <rhs>"namespace-node"  "("  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-AnyXNodeType">
                        <lhs>AnyXNodeType</lhs>
                        <rhs>"node"  "("  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-TypeTest-JNodeType">
                        <lhs>JNodeType</lhs>
                        <rhs>"jnode"  "("  (("*"  |  <nt def="prod-xquery40-JRootSelector">JRootSelector<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt>)  (","  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
                     </prod>
                  </scrap>
                  <!--<p>The most general form of type test uses the syntax 
           <code>type(<var>ItemType</var>)</code>. This selects GNodes
        that are instances of </p>
               
        <ulist>
           <item><p>XNodes that are instances of the supplied <var>SequenceType</var>;</p></item>
           <item><p>JNodes whose <term>·jvalue·</term> property is an instance of the 
              supplied <var>SequenceType</var>.</p></item>
        </ulist>-->
                  <p>For example:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">element(N)</code> (short for <code nobreak="false">child::element(N)</code>) selects
               elements named <var>N</var>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">attribute(*, xs:integer)</code>selects
               attribute nodes whose type annotation is <code nobreak="false">xs:integer</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">text()</code> selects text nodes.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">jnode("id")</code> selects JNodes having the <term>·jkey·</term> property <code nobreak="false">"id"</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">jnode(*, map(*))</code> selects JNodes whose <term>·jvalue·</term> property is an instance
               of the type <code nobreak="false">map(*)</code>.</p>
                     </item>
                  </ulist>
                  <!--<p>For the most commonly encountered types, this syntax can be abbreviated: for example
           <code>node()</code>, <code>text()</code>, <code>array(*)</code>, and <code>record(x, y)</code>
           can be written directly without the enclosing <code>type(...)</code>.</p>
               
        <p>If the origin is an XNode the type used will normally be a 
           <nt def="NodeKindTest">NodeKindTest</nt> such as <code>node()</code>
           or <code>comment()</code>. Specifying a type that cannot select nodes,
           such as <code>map(*)</code>, is allowed but pointless.</p>
               
        <note><p>If <var>T</var> is a <nt def="NodeKindTest">NodeKindTest</nt>, there is
        a subtle difference between the expressions <code>$N/T</code> and
        <code>$N/type(T)</code>: if no explicit axis is specified, and if <var>T</var>
        is in the form <code>attribute(N)</code> or <code>schema-attribute(N)</code>, this
        changes the default axis to be the attribute axis; and similarly for tests implicitly
        using the namespace axis. This rule does not apply when the step is
        written as <code>type(attribute(N))</code> or <code>type(schema-attribute(N))</code>.
        Such constructs make sense, for example, when selecting members of an array that
        are XNodes: the expressions <code>$array/type(element(*))</code> and <code>$array/type(attribute(*))</code>
        can be used to select the members of an array that are element nodes or attribute nodes
        respectively.</p>
        <p>Such expressions return a sequence of JNodes, whose <term>·jvalue·</term> property is 
        an XNode. Note that it is not directly possible to start with a JNode, select
        a contained XNode, and then navigate from the XNode: a path such as <code>$array/type(element(p))/@id</code>
        will not work. This is because the first step, <code>$array/type(element(p))</code>, does not select
        an element node, it selects a JNode whose <term>·jvalue·</term> property is that element node, and use of the
        attribute axis starting from a JNode has no effect.</p>
        <p>Instead, the required effect can be achieved by adding a step that explicitly 
           extracts the content of the JNode: <code>$array/type(element(p))/jvalue()/@id</code>.</p>   
        </note>       -->
                  <p>The syntax
		  and semantics of <nt def="prod-xquery40-XNodeType"><!--$spec = xquery40--></nt> and <nt def="doc-xquery40-JNodeType"><!--$spec = xquery40--></nt>
           are described in <specref ref="id-sequencetype-syntax"/> and <specref ref="id-sequencetype-matching"/>.</p>
                  <p>Shown below are further examples of type tests that might
		  be used in path expressions selecting within an XTree:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">node()</code> matches any XNode.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">text()</code> matches
		  any text
		  node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">comment()</code>
		  matches any comment
		  node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">namespace-node()</code> matches any
		  namespace node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element()</code>
		  matches any element
		  node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">schema-element(person)</code>
		  matches any element node whose name is
		  <code nobreak="false">person</code> (or is in the <termref def="dt-substitution-group">substitution group</termref>
		  headed by <code nobreak="false">person</code>), and whose type
		  annotation is the same as (or is derived from) the declared type of the <code nobreak="false">person</code>
		  element in the <termref def="dt-is-elems">in-scope element declarations</termref>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person)</code> matches any element node whose name is
		  <code nobreak="false">person</code>, regardless of its type annotation.</p>
                     </item>
                     <item diff="add" at="Issue23">
                        <p>
                           <code role="parse-test" nobreak="false">element(doctor|nurse)</code> matches any element node whose name is
                        <code nobreak="false">doctor</code> or <code nobreak="false">nurse</code>, regardless of its type annotation.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(person, surgeon)</code> matches any non-nilled element node whose name
		  is <code nobreak="false">person</code>, and whose type
		  annotation is
		  <code nobreak="false">surgeon</code> or is derived from <code nobreak="false">surgeon</code>.</p>
                     </item>
                     <item diff="add" at="Issue23">
                        <p>
                           <code role="parse-test" nobreak="false">element(doctor|nurse, medical-staff)</code> matches any non-nilled element node whose name
                        is <code nobreak="false">doctor</code> or <code nobreak="false">nurse</code>, and whose type
                        annotation is
                        <code nobreak="false">medical-staff</code> or is derived from <code nobreak="false">medical-staff</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">element(*,
		  surgeon)</code> matches any non-nilled element node whose type
		  annotation is <code nobreak="false">surgeon</code> (or is derived from <code nobreak="false">surgeon</code>), regardless of
		  its
		  name.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">attribute()</code> matches any
                  attribute node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">attribute(price)</code> matches
                  any attribute whose name is <code nobreak="false">price</code>,
                  regardless of its type annotation.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">attribute(*,
                  xs:decimal)</code> matches any attribute whose type
                  annotation is <code nobreak="false">xs:decimal</code> (or is derived from <code nobreak="false">xs:decimal</code>), regardless of
                  its
                  name.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">document-node()</code>
                  matches any document
                  node.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">document-node(element(book))</code>
                  matches any document node whose children consist of
                  a single element node that satisfies the <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>
                           <code role="parse-test" nobreak="false">element(book)</code>, interleaved with zero or more
                  comments and processing
                  instructions, and no text nodes.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">document-node(book)</code> is an abbreviation
                  for <code nobreak="false">document-node(element(book))</code>.</p>
                     </item>
                  </ulist>
                  <p>The following examples show type type tests that might
		  be used in path expressions selecting within a JTree:</p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">jnode(*, array(*))</code> matches any JNode
                        whose <term>·jvalue·</term> is an array.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">jnode(*, record(longitude, latitude, *))</code> matches any JNode
                     whose <term>·jvalue·</term> is a map having entries with keys
                     <code nobreak="false">"longitude"</code> and <code nobreak="false">"latitude"</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">jnode(*, empty-sequence())</code> matches any JNode
                     whose <term>·jvalue·</term> is the empty sequence.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">jnode(*, xs:date)</code> matches any JNode
                     whose <term>·jvalue·</term> is an instance of <code nobreak="false">xs:date</code>.</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="implausible-axis-steps" diff="add" at="Issue602">
                  <head>Implausible Axis Steps</head>
                  <changes>
                     <change issue="602" PR="603" date="2023-07-25">
                     The rules for reporting type errors during static analysis have been changed
                     so that a processor has more freedom to report errors in respect of constructs that
                     are evidently wrong, such as <code nobreak="false">@price/@value</code>, even though dynamic evaluation
                     is defined to return the empty sequence rather than an error.
                  </change>
                  </changes>
                  <p>Certain axis steps, given an inferred type for the context value, are
               classified as <termref def="dt-implausible"/>. During the static analysis
               phase, a processor <rfc2119>may</rfc2119> (subject to the rules in
               <specref ref="id-implausible-expressions"/>) report a static error
               when such axis steps are encountered: <errorref class="TY" code="0144"/>.</p>
                  <p>More specifically, an axis step is classified as <termref def="dt-implausible"/>
               if any of the following conditions applies:</p>
                  <olist>
                     <item>
                        <p>The inferred item type of the context value is a node kind for which the
                     specified axis is always empty: for example, the inferred item type
                     of the context value is <code nobreak="false">attribute()</code> 
                     and the axis is <code nobreak="false">child</code>.</p>
                     </item>
                     <item>
                        <p>The node test exclusively selects node kinds that cannot appear
                  on the specified axis: for example, the axis is <code nobreak="false">child</code>
                  and the node test is <code nobreak="false">document-node()</code>.</p>
                     </item>
                     <item>
                        <p>In a schema-aware environment, when using the <code nobreak="false">child</code>,
                     <code nobreak="false">descendant</code>, <code nobreak="false">descendant-or-self</code>, or <code nobreak="false">attribute</code>
                     axes, the inferred item type of the
                     context value has a content type that does not allow any node matching
                  the node test to be present on the relevant axis. For example, if the inferred
                  item type of the context value 
                  is <code nobreak="false">schema-element(list)</code> and the relevant element declaration 
                     (taking into account substitution group membership and wildcards) 
                     only allows <code nobreak="false">item</code> children,
                  the axis step <code nobreak="false">child::li</code> will never select anything and is therefore
                  classified as <termref def="dt-implausible"/>.</p>
                     </item>
                  </olist>
                  <p>Examples of implausible axis steps include the following:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">@code/text()</code>: attributes cannot have text node children.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">/@code</code>: document nodes cannot have attributes.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">ancestor::text()</code>: the ancestor axis never returns text nodes.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">element(*)/child::map</code>: the child axis starting at an element node
                     will never select a map.</p>
                     </item>
                  </ulist>
                  <note>
                     <p>Processors may choose not to classify the expression <code nobreak="false">/..</code>
               as implausible, since XSLT 1.0 users were sometimes advised to use this construct
               as an explicit way of denoting the empty sequence.</p>
                  </note>
               </div4>
            </div3>
            <div3 id="id-predicate">
               <head>Predicates within Steps</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-Predicate">
                     <lhs>Predicate</lhs>
                     <rhs>"["  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "]"</rhs>
                  </prod>

                  <prod id="doc-xquery40-Predicate-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>
               </scrap>
               <p id="dt-predicate">A predicate within an <nt def="doc-xquery40-AxisStep">AxisStep<!--$spec = xquery40--></nt> has similar syntax and semantics
	 to a predicate within a <termref def="dt-filter-expression"/>.  The
	 only difference is in the way the context position is set for
	 evaluation of the predicate.</p>
               <note>
                  <p>The operator <code nobreak="false">[]</code> binds more tightly than <code nobreak="false">/</code>.
            This means that the expression <code nobreak="false">a/b[1]</code> is interpreted as <code nobreak="false">child::a/(child::b[1])</code>:
                  it selects the first <code nobreak="false">b</code>
            child of every <code nobreak="false">a</code> element, in contrast to <code nobreak="false">(a/b)[1]</code> which
            selects the first <code nobreak="false">b</code> element that is a child of some <code nobreak="false">a</code>
            element.</p>
                  <p>A common mistake is to write <code nobreak="false">//a[1]</code> where <code nobreak="false">(//a)[1]</code>
               is intended. The first expression, <code nobreak="false">//a[1]</code>, selects every descendant 
                  <code nobreak="false">a</code> element that is the first child of its parent (it expands
                  to <code nobreak="false">/descendant-or-self::node()/child::a[1]</code>), whereas 
               <code nobreak="false">(//a)[1]</code> selects the <code nobreak="false">a</code> element in the document.
               </p>
               </note>
               <p>For the purpose of evaluating the context position within
	 a predicate, the input sequence is considered to be sorted as
	 follows: into document order if the predicate is in a
	 forward-axis step, into reverse document order if the
	 predicate is in a reverse-axis step, or in its original order
	 if the predicate is not in a step.</p>
               <p>More formally:</p>
               <ulist>
                  <item>
                     <p>For a step using a forwards axis, such as <code nobreak="false">child::<var>test</var>[<var>P</var>]</code>,
               the result is the same as for the equivalent <termref def="dt-filter-expression"/>
                        <code nobreak="false">(child::<var>test</var>)[<var>P</var>]</code> (note the parentheses). The same applies if there
               are multiple predicates, for example <code nobreak="false">child::<var>test</var>[<var>P1</var>][<var>P2</var>][<var>P3</var>]</code>
               is equivalent to <code nobreak="false">(child::<var>test</var>)[<var>P1</var>][<var>P2</var>][<var>P3</var>]</code>.</p>
                  </item>
                  <item>
                     <p>For a step using a reverse axis, such as <code nobreak="false">ancestor::<var>test</var>[<var>P</var>]</code>,
               the result is the same as the expression  
               <code nobreak="false">reverse(ancestor::<var>test</var>)[<var>P</var>] =&gt; reverse()</code>. The same applies if there
               are multiple predicates, for example <code nobreak="false">ancestor::<var>test</var>[<var>P1</var>][<var>P2</var>][<var>P3</var>]</code>
               is equivalent to <code nobreak="false">reverse(ancestor::<var>test</var>)[<var>P1</var>][<var>P2</var>][<var>P3</var>] =&gt; reverse()</code>.</p>
                  </item>
               </ulist>
               <note>
                  <p>The result of the expression <code nobreak="false">preceding-sibling::*</code> is in document order, but
               <code nobreak="false">preceding-sibling::*[1]</code> selects the last preceding sibling element,
               that is, the one that immediately precedes the context node.</p>
                  <p>Similarly, the expression <code nobreak="false">preceding-sibling::x[1, 2, 3]</code> selects the last three
               preceding siblings, returning them in document order. For example, given the input:</p>
                  <eg xml:space="preserve">&lt;doc&gt;&lt;a/&gt;&lt;b/&gt;&lt;c/&gt;&lt;d/&gt;&lt;e/&gt;&lt;f/&gt;&lt;/doc&gt;</eg>
                  <p>The result of <code nobreak="false">//e ! preceding-sibling::*[1, 2, 3]</code> is <code nobreak="false">&lt;b/&gt;, &lt;c/&gt;, &lt;d/&gt;</code>.
               The expression <code nobreak="false">//e ! preceding-sibling::*[3, 2, 1]</code> delivers exactly the same result.</p>
               </note>
               <p>Here are some examples of <termref def="dt-axis-step">axis steps</termref> that contain predicates to select XNodes:</p>
               <ulist>
                  <item>
                     <p>This example selects the second <code nobreak="false">chapter</code> element that is a child
			 of the context node:</p>
                     <eg role="parse-test" xml:space="preserve">child::chapter[2]</eg>
                  </item>
                  <item>
                     <p>This example selects all the descendants of the
		  context node that are elements named
		  <code nobreak="false">"toy"</code> and whose <code nobreak="false">color</code>
		  attribute has the value <code nobreak="false">"red"</code>:</p>
                     <eg role="parse-test" xml:space="preserve">descendant::toy[attribute::color = "red"]</eg>
                  </item>
                  <item>
                     <p>This example selects all the <code nobreak="false">employee</code> children of the context node
		that have both a <code nobreak="false">secretary</code> child element and an <code nobreak="false">assistant</code> child element:</p>
                     <eg role="parse-test" xml:space="preserve">child::employee[secretary][assistant]</eg>
                  </item>
                  <item>
                     <p>This example selects the innermost <code nobreak="false">div</code> ancestor of the context node:</p>
                     <eg role="parse-test" xml:space="preserve">ancestor::div[1]</eg>
                  </item>
                  <item>
                     <p>This example selects the outermost <code nobreak="false">div</code> ancestor of the context node:</p>
                     <eg role="parse-test" xml:space="preserve">ancestor::div[last()]</eg>
                  </item>
                  <item>
                     <p>This example selects the names of all the ancestor elements of the context node that have an
                     <code nobreak="false">@id</code> attribute, outermost element first:</p>
                     <eg role="parse-test" xml:space="preserve">ancestor::*[@id]</eg>
                  </item>
               </ulist>
               <note>
                  <p>The expression <code role="parse-test" nobreak="false">ancestor::div[1]</code> parses as an <nt def="doc-xquery40-AxisStep">AxisStep<!--$spec = xquery40--></nt>
                  with a reverse axis, and the position <code nobreak="false">1</code> therefore
                  refers to the first ancestor <code nobreak="false">div</code> in reverse document order,
                  that is, the innermost <code nobreak="false">div</code>. By
contrast, <code role="parse-test" nobreak="false">(ancestor::div)[1]</code> parses as a <nt def="doc-xquery40-FilterExpr">FilterExpr<!--$spec = xquery40--></nt>,
                  and therefore returns the first qualifying <code nobreak="false">div</code>
element in the order of the <code nobreak="false">ancestor::div</code> expression, which is
                  in <termref def="dt-document-order"/>.</p>
                  <p>The fact that a reverse-axis step assigns context positions in reverse
document order for the purpose of evaluating predicates does not alter the
fact that the final result of the step is always in document order.</p>
                  <p diff="add" at="2022-01-17">The expression <code nobreak="false">ancestor::(div1|div2)[1]</code> 
               does not have the same meaning as <code nobreak="false">(ancestor::div1|ancestor::div2)[1]</code>. 
                  In the first expression,
               the predicate <code nobreak="false">[1]</code> is within a step that uses a reverse axis, so nodes are counted
               in reverse document order. In the second expression, the predicate applies to the result of
               a union expression, so nodes are counted in document order.</p>
               </note>
               <p>When the context value for evaluation of a step includes multiple GNodes, the step is evaluated
            separately for each of those GNodes, and the results are combined, eliminating duplicates
            and sorting into document order.</p>
               <note>
                  <p>To avoid reordering and elimination of duplicates, replace the step <code nobreak="false">S</code> by <code nobreak="false">.!S</code>.</p>
               </note>
            </div3>
            <div3 id="unabbrev">
               <head>Unabbreviated Syntax</head>
               <p>This section provides a number of examples of path expressions in which the
axis is explicitly specified in each <termref def="dt-step">step</termref>. The syntax used in these examples is
called the <term>unabbreviated syntax</term>. In many common cases, it is
possible to write path expressions more concisely using an <term>abbreviated
syntax</term>, as explained in <specref ref="abbrev"/>.</p>
               <p>These examples assume that the context value is a single node, referred to as the context node.</p>
               <ulist>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para</code> selects
the <code nobreak="false">para</code> element children of the context node.</p>
                  </item>
                  <item diff="add" at="2022-12-13">
                     <p>
                        <code role="parse-test" nobreak="false">child::(para|bullet)</code> selects
                     the <code nobreak="false">para</code> and <code nobreak="false">bullet</code> element children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::*</code> selects all element children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::text()</code> selects all text node children of the context node.</p>
                  </item>
                  <item diff="add" at="2022-12-13">
                     <p>
                        <code role="parse-test" nobreak="false">child::(text()|comment())</code> selects all text node and comment node children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::node()</code> selects all the children of the context node. Note that no attribute nodes are returned, because attributes are not children.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">attribute::name</code> selects the <code nobreak="false">name</code> attribute of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">attribute::*</code> selects all the attributes of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">parent::node()</code> selects the parent of the context node. If the context node is an attribute node, this expression returns the element node (if any) to which the attribute node is attached.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">descendant::para</code> selects the <code nobreak="false">para</code> element descendants of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">ancestor::div</code> selects all <code nobreak="false">div</code> ancestors of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">ancestor-or-self::div</code> selects the <code nobreak="false">div</code> ancestors of the context node and, if the context node is a <code nobreak="false">div</code> element, the context node as well.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">descendant-or-self::para</code> selects the <code nobreak="false">para</code> element descendants of the context node and, if the context node is a <code nobreak="false">para</code> element, the context node as well.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">self::para</code> selects the context node if it is a <code nobreak="false">para</code> element, and otherwise returns the empty sequence.</p>
                  </item>
                  <item diff="add" at="2022-12-13">
                     <p>
                        <code role="parse-test" nobreak="false">self::(chapter|appendix)</code> selects the context node if it is a
                     <code nobreak="false">chapter</code> or <code nobreak="false">appendix</code> element, and otherwise returns the empty sequence.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::chapter/descendant::para</code> selects the <code nobreak="false">para</code> element
descendants of the <code nobreak="false">chapter</code> element children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::*/child::para</code> selects all <code nobreak="false">para</code> grandchildren of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">/</code> selects the root of the tree that contains the context node, but raises a dynamic error if this root is not a document node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">/descendant::para</code> selects all the <code nobreak="false">para</code> elements in the same document as the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">/descendant::list/child::member</code> selects all
the <code nobreak="false">member</code> elements that have a <code nobreak="false">list</code> parent and that are in the same document as the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para[position() = 1]</code> selects the first <code nobreak="false">para</code> child of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para[position() = last()]</code> selects the last <code nobreak="false">para</code> child of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para[position() = last()-1]</code> selects the last but one <code nobreak="false">para</code> child of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para[position() &gt; 1]</code> selects all the <code nobreak="false">para</code> children of the context node other than the first <code nobreak="false">para</code> child of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">following-sibling::chapter[position() = 1]</code> selects the next <code nobreak="false">chapter</code> sibling of the context node.</p>
                  </item>
                  <item diff="add" at="2022-12-13">
                     <p>
                        <code role="parse-test" nobreak="false">following-sibling::(chapter|appendix)[position() = 1]</code> selects the next sibling of the context node
                        that is either a <code nobreak="false">chapter</code> or an <code nobreak="false">appendix</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">preceding-sibling::chapter[position() = 1]</code> selects the previous <code nobreak="false">chapter</code> sibling of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">/descendant::figure[position() = 42]</code> selects the forty-second <code nobreak="false">figure</code> element in the document containing the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">/child::book/child::chapter[position() = 5]/child::section[position() = 2]</code> selects the
second <code nobreak="false">section</code> of the fifth <code nobreak="false">chapter</code> of the <code nobreak="false">book</code> whose parent is the document node that contains the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para[attribute::type eq "warning"]</code> selects
all <code nobreak="false">para</code> children of the context node that have a <code nobreak="false">type</code> attribute with value <code nobreak="false">warning</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para[attribute::type eq 'warning'][position() = 5]</code> selects the fifth <code nobreak="false">para</code> child of the context node that has a <code nobreak="false">type</code> attribute with value <code nobreak="false">warning</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::para[position() = 5][attribute::type eq "warning"]</code> selects the fifth <code nobreak="false">para</code> child of the context node if that child has a <code nobreak="false">type</code> attribute with value <code nobreak="false">warning</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::chapter[child::title = 'Introduction']</code> selects
the <code nobreak="false">chapter</code> children of the context node that have one or
more <code nobreak="false">title</code> children whose <termref def="dt-typed-value">typed value</termref> is equal to the
string <code nobreak="false">Introduction</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::chapter[child::title]</code> selects the <code nobreak="false">chapter</code> children of the context node that have one or more <code nobreak="false">title</code> children.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::*[self::chapter or self::appendix]</code>
selects the <code nobreak="false">chapter</code> and <code nobreak="false">appendix</code> children of the context node.</p>
                  </item>
                  <item diff="chg" at="2022-12-13">
                     <p>
                        <code role="parse-test" nobreak="false">child::*[self::(chapter|appendix)][position() = last()]</code> selects the
last <code nobreak="false">chapter</code> or <code nobreak="false">appendix</code> child of the context node.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="abbrev">
               <head>Abbreviated Syntax</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-AbbreviatedStep">
                     <lhs>AbbreviatedStep</lhs>
                     <rhs>".."  |  ("@"  <nt def="doc-xquery40-NodeTest">NodeTest<!--$idref_lang_part = xquery40- --></nt>)  |  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AbbreviatedStep-NodeTest">
                     <lhs>NodeTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-UnionNodeTest">UnionNodeTest<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AbbreviatedStep-SimpleNodeTest">
                     <lhs>SimpleNodeTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TypeTest">TypeTest<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Selector">Selector<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AbbreviatedStep-TypeTest">
                     <lhs>TypeTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-GNodeType">GNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-XNodeType">XNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-JNodeType">JNodeType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AbbreviatedStep-Selector">
                     <lhs>Selector</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>  |  ("get"  "("  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  ")")</rhs>
                  </prod>

                  <prod id="doc-xquery40-AbbreviatedStep-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-AbbreviatedStep-Wildcard">
                     <lhs>Wildcard</lhs>
                     <rhs>"*"<br/>|  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":*")<br/>|  ("*:"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>)<br/>|  (<nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  "*")</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-AbbreviatedStep-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>The abbreviated syntax for a step permits the following abbreviations:</p>
               <olist>
                  <item>
                     <p>The attribute axis <code nobreak="false">attribute::</code> can be
    abbreviated by <code nobreak="false">@</code>. For example, the expression <code role="parse-test" nobreak="false">para[@type = "warning"]</code> is short
    for <code role="parse-test" nobreak="false">child::para[attribute::type = "warning"]</code> and
    so selects <code nobreak="false">para</code> children with a <code nobreak="false">type</code> attribute with value
    equal to <code nobreak="false">warning</code>.</p>
                  </item>
                  <item>
                     <p>If the axis name is omitted from an <termref def="dt-axis-step">axis step</termref>, the default axis is
    <code nobreak="false">child</code>, with two exceptions:

    (1) if the <nt def="doc-xquery40-NodeTest">NodeTest<!--$spec = xquery40--></nt> in an axis step contains an 
                     <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt> or <nt def="doc-xquery40-SchemaAttributeNodeType"><!--$spec = xquery40--></nt> then the
    default axis is <code nobreak="false">attribute</code>;     
    (2) if the <nt def="doc-xquery40-NodeTest">NodeTest<!--$spec = xquery40--></nt> in an axis step is a <nt def="prod-xquery40-NamespaceNodeType"><!--$spec = xquery40--></nt>
                        <phrase role="xquery">then a static error
    is raised <errorref class="ST" code="0134"/>.</phrase>
                        <note>
                           <p> The namespace
    axis is deprecated as of XPath 2.0, but is required in some languages
    that use XPath, including XSLT.</p>
                        </note>

    For example, the path expression <code role="parse-test" nobreak="false">section/para</code> is an abbreviation for <code role="parse-test" nobreak="false">child::section/child::para</code>, and the path
    expression <code role="parse-test" nobreak="false">section/@id</code> is an
    abbreviation for <code role="parse-test" nobreak="false">child::section/attribute::id</code>.  Similarly,
    <code role="parse-test" nobreak="false">section/attribute(id)</code> is an
    abbreviation for <code role="parse-test" nobreak="false">child::section/attribute::attribute(id)</code>. Note
    that the latter expression contains both an axis specification and
    a <termref def="dt-node-test">node test</termref>.</p>
                     <p>Similarly, within a JTree rooted at an array, the expression <code nobreak="false">get(1)/parts/get(2)/part-no</code>
                  gets the first member of the top-level array (presumably a map), then the <code nobreak="false">"parts"</code>
                  entry within this map (presumably an array), then the second member of this array (presumably
                  a map), and finally the <code nobreak="false">part-no</code> entry within this map.</p>
                     <note>
                        <p>The same selection could be made using the lookup expression <code nobreak="false">?1?parts?2?part-no</code>.
                  The main difference is that path expressions offer more flexibility in being able to navigate around
                  the containing JTree. Also, the lookup expression <code nobreak="false">$a?1</code> fails if the
                  array index is out of bounds; the path expression <code nobreak="false">$a/get(1)</code> 
                  (or <code nobreak="false">$a/*[1]</code>) instead returns the empty sequence.</p>
                     </note>
                     <note diff="add" at="2022-12-13">
                        <p>An abbreviated axis step that omits the axis name must use a
                  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$spec = xquery40--></nt> rather than a <nt def="prod-xquery40-UnionNodeTest">UnionNodeTest<!--$spec = xquery40--></nt>.
                  This means that a construct such as <code nobreak="false">(ul|ol)</code>
                  is treated as an abbreviation for <code nobreak="false">(child::ul|child::ol)</code> rather than <code nobreak="false">child::(ul|ol)</code>.
                  Since the two constructs have exactly the same semantics, this is not actually a restriction.</p>
                     </note>
                  </item>
                  <item>
                     <p>A step consisting
of <code role="parse-test" nobreak="false">..</code> is short
for <code role="parse-test" nobreak="false">parent::gnode()</code>. For example (assuming the context
                     item is an XNode), <code role="parse-test" nobreak="false">../title</code> is short for <code role="parse-test" nobreak="false">parent::gnode()/child::title</code> and so will select the 
                     <code nobreak="false">title</code> children of the parent of the context node.</p>
                     <p>Similarly, if <code nobreak="false">$dateOfBirth</code> is a JNode resulting from the expression
                  <code nobreak="false">$map/get("date of birth")</code>, then <code nobreak="false">$dateOfBirth/../gender</code>
                  will select the entry having key <code nobreak="false">"gender"</code> within <code nobreak="false">$map</code>.</p>
                     <note>
                        <p>The expression <code nobreak="false">.</code>, known as a <term>context value
   reference</term>, is a <termref def="dt-primary-expression">primary expression</termref>,
   and is described in <specref ref="id-context-value-references"/>.</p>
                     </note>
                  </item>
               </olist>
               <p>Here are some examples of path expressions that use the abbreviated
syntax. These examples assume that the context value is a single XNode, referred to as the context node:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">para</code> selects the <code nobreak="false">para</code> element children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">*</code> selects all element children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">text()</code> selects all text node children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">@name</code> selects
the <code nobreak="false">name</code> attribute of the context node.</p>
                  </item>
                  <item diff="add" at="2022-12-13">
                     <p>
                        <code role="parse-test" nobreak="false">@(id|name)</code> selects
                     the <code nobreak="false">id</code> and <code nobreak="false">name</code> attributes of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">@*</code> selects all the attributes of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">para[1]</code> selects the first <code nobreak="false">para</code> child of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">para[last()]</code> selects the last <code nobreak="false">para</code> child of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">*/para</code> selects
all <code nobreak="false">para</code> grandchildren of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">/book/chapter[5]/section[2]</code> selects the
second <code nobreak="false">section</code> of the fifth <code nobreak="false">chapter</code> of the <code nobreak="false">book</code> whose parent is the document node that contains the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">chapter//para</code> selects the <code nobreak="false">para</code> element descendants of the <code nobreak="false">chapter</code> element children of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">//para</code> selects all
the <code nobreak="false">para</code> descendants of the root document node and thus selects all <code nobreak="false">para</code> elements in the same document as the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">//@version</code> selects all the <code nobreak="false">version</code> attribute nodes that are in the same document as the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">//list/member</code> selects all the <code nobreak="false">member</code> elements in the same document as the context node that have a <code nobreak="false">list</code> parent.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">.//para</code> selects
the <code nobreak="false">para</code> element descendants of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">..</code> selects the parent of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">../@lang</code> selects
the <code nobreak="false">lang</code> attribute of the parent of the context node.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">para[@type = "warning"]</code> selects all <code nobreak="false">para</code> children of the context node that have a <code nobreak="false">type</code> attribute with value <code nobreak="false">warning</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">para[@type = "warning"][5]</code> selects the fifth <code nobreak="false">para</code> child of the context node that has a <code nobreak="false">type</code> attribute with value <code nobreak="false">warning</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">para[5][@type = "warning"]</code> selects the fifth <code nobreak="false">para</code> child of the context node if that child has a <code nobreak="false">type</code> attribute with value <code nobreak="false">warning</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">chapter[title = "Introduction"]</code> selects the <code nobreak="false">chapter</code> children of the context node that have one
or more <code nobreak="false">title</code> children whose <termref def="dt-typed-value">typed value</termref> is equal to the string <code nobreak="false">Introduction</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">chapter[title]</code> selects the <code nobreak="false">chapter</code> children of the context node that have one or more <code nobreak="false">title</code> children.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">employee[@secretary and @assistant]</code> selects all
the <code nobreak="false">employee</code> children of the context node that have both a <code nobreak="false">secretary</code> attribute and
an <code nobreak="false">assistant</code> attribute.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">book/(chapter|appendix)/section</code> selects
every <code nobreak="false">section</code> element that has a parent that is either a <code nobreak="false">chapter</code> or an <code nobreak="false">appendix</code> element, that in turn is a child of a <code nobreak="false">book</code> element that is a child of the context node.</p>
                  </item>
                  <item>
                     <p>If <code nobreak="false">E</code> is any expression that returns a sequence of nodes, then the expression <code role="parse-test" nobreak="false">E/.</code> returns the same nodes in <termref def="dt-document-order">document order</termref>, with duplicates eliminated based on node identity.</p>
                  </item>
               </ulist>
               <p>The following examples use abbreviated paths to access data within the JTree
               obtained by parsing the JSON text:</p>
               <eg xml:space="preserve">[
  { "first": "John", 
    "last": "Baker", 
    "date of birth": "2003-04-19", 
    "occupation": "cook"}, 
  { "first": "Mary", 
    "last": "Smith", 
    "date of birth": "2006-08-12", 
    "occupation": "teacher"},                 
]</eg>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">get(1)/first</code> returns a JNode whose <term>·jvalue·</term>
               is the string <code nobreak="false">"John"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">//first[. = "Mary"]/../last</code> returns a JNode whose <term>·jvalue·</term>
               is the string <code nobreak="false">"Smith"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">//first[. = "Mary"]/../get("date of birth")</code> returns a JNode whose <term>·jvalue·</term>
               is the string <code nobreak="false">"2006-08-12"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">//*[occupation = "cook"]!`{first} {last}`</code> returns the
               string <code nobreak="false">"John Baker"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">//*[occupation = "cook"]/following-sibling::*[1]!`{first} {last}`</code> returns the
               string <code nobreak="false">"Mary Smith"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">//*[last = "Smith"]/../get(1)/last</code> returns the
               string <code nobreak="false">"Baker"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">//record(first, last, *) ! string(last)</code> returns the sequence of two
               strings <code nobreak="false">"Baker"</code>, <code nobreak="false">"Smith"</code>.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="comparison-with-JSONPath">
               <head>Comparison with JSONPath</head>
               <p>Path expressions applied to a JTree offer similar capability to
            JSONPath, which is an XPath-like language design for querying JSON.</p>
               <example>
                  <head>Comparison with JSONPath</head>
                  <p>This example provides XPath equivalents to some examples given in the
                  JSONPath specification. [TODO: add a reference].</p>
                  <p>The examples query the result of parsing the following JSON value, representing
                     a store whose stock consists of four books and a bicycle:</p>
                  <eg xml:space="preserve">{
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 399
    }
  }
}</eg>
                  <p>The following table illustrates some queries on this data, expressed
                  both in JSONPath and in XQuery 4.0.</p>
                  <table role="small" width="100%">
                     <caption>JSONPath vs XQuery 4.0 Comparison</caption>
                     <col width="40%" span="1"/>
                     <col width="30%" span="1"/>
                     <col width="30%" span="1"/>
                     <thead>
                        <tr>
                           <th rowspan="1" colspan="1">Query</th>
                           <th rowspan="1" colspan="1">JSONPath</th>
                           <th rowspan="1" colspan="1">XQuery 4.0</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">The authors of all books in the store</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$.store.book[*].author</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">/store/book//author</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">All authors</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..author</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//author</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">All things in store (four books and a red bicycle)</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$.store.*</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">/store/*</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">The prices of everything in the store</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$.store..price</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">/store//price</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">The third book</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..book[2]  </code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//book/*[3]</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">The third book's author</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..book[2].author</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//book/*[3]/author</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">The third book's publisher (empty result)</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..book[2].publisher</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//book/*[3]/publisher</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">The last book (in order)</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..book[-1]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//book/*[last()]</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">The first two books</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..book[0,1]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//book/*[1,2]</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">All books with an ISBN</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..book[?@.isbn]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//book[isbn]</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">All books cheaper than 10</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..book[?@.price&lt;10]</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//book[price lt 10]</code>
                           </td>
                        </tr>
                        <tr>
                           <td valign="top" rowspan="1" colspan="1">All member values and array elements contained in the input value</td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">$..*</code>
                           </td>
                           <td valign="top" rowspan="1" colspan="1">
                              <code nobreak="false">//*</code>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </example>
            </div3>
         </div2>
         <div2 id="id-sequence-expressions">
            <head>Sequence Expressions</head>
            <p>XQuery 4.0 supports operators to construct, filter,  and combine
<termref def="dt-sequence">sequences</termref> of <termref def="dt-item">items</termref>.
Sequences are never nested—for
example, combining the values <code nobreak="false">1</code>, <code nobreak="false">(2, 3)</code>, and <code nobreak="false">( )</code> into a single sequence results
in the sequence <code nobreak="false">(1, 2, 3)</code>.</p>
            <div3 id="construct_seq">
               <head>Sequence Concatenation</head>
               <scrap headstyle="show">
                  <prod id="x2-x2-doc-xquery40-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="x2-x2-doc-xquery40-Expr-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>
                  <termdef id="dt-sequence-expression" term="sequence expression">A
            <term>sequence expression</term> is a <termref def="dt-non-trivial"/> instance
            of the production rule <nt def="doc-xquery40-Expr">Expr<!--$spec = xquery40--></nt>, that is, an expression
            containing two or more instances of the production <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt>
            separated by the comma operator.</termdef>
               </p>
               <p>The result of a <termref def="dt-sequence-expression"/> is the
            <termref def="dt-sequence-concatenation"/> of the values of its operands.
            See <nt def="doc-xquery40-Expr"><!--$spec = xquery40--></nt>
               </p>
               <p>
                  <termdef term="comma operator" id="dt-comma-operator">A <term>comma operator</term> is a comma used specifically
                  as the operator in a <termref def="dt-sequence-expression"/>.</termdef>
               </p>
               <p>Empty parentheses can be used to denote the empty sequence.</p>
               <p>A sequence may contain duplicate
<termref def="dt-item">items</termref>, but a sequence is never an item in another sequence. When a
new sequence is created by concatenating two or more input sequences, the new
sequence contains all the items of the input sequences and its length is the
sum of the lengths of the input sequences.</p>
               <p>
                  <termdef id="dt-sequence-concatenation" term="sequence concatenation">The 
               <term>sequence concatenation</term> of a number of sequences <var>S/1</var>, <var>S/2</var>, ... <var>S/n</var>
               is defined to be the sequence formed from the items of <var>S/1</var>, followed by the items
               from <var>S/2</var>, and so on, retaining order.</termdef> The 
               <termref def="dt-comma-operator"/> returns the sequence
            concatenation of its two operands; repeated application (for example <code nobreak="false">$s1, $s2, $s3, $s4</code>)
            delivers the sequence concatenation of multiple sequences.</p>
               <note>
                  <p>In places where the grammar calls for <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt>, such as the arguments of a function call, any expression that contains a top-level comma operator must be enclosed in parentheses.</p>
               </note>
               <p>Here are some examples of expressions that construct sequences:
</p>
               <ulist>
                  <item>
                     <p>The result of this expression is a sequence of five integers:</p>
                     <eg role="parse-test" xml:space="preserve">(10, 1, 2, 3, 4)</eg>
                  </item>
                  <item>
                     <p>This expression combines four sequences of length one, two, zero, and two, respectively, into a single sequence of length five. The result of this expression is the sequence <code nobreak="false">10, 1, 2, 3, 4</code>.</p>
                     <eg role="parse-test" xml:space="preserve">(10, (1, 2), (), (3, 4))</eg>
                  </item>
                  <item>
                     <p>The result of this expression is a sequence containing
all <code nobreak="false">salary</code> children of the context node followed by all <code nobreak="false">bonus</code> children.</p>
                     <eg role="parse-test" xml:space="preserve">(salary, bonus)</eg>
                  </item>
                  <item>
                     <p>Assuming that <code nobreak="false">$price</code> is bound to
the value <code nobreak="false">10.50</code>, the result of this expression is the sequence <code nobreak="false">10.50, 10.50</code>.</p>
                     <eg role="parse-test" xml:space="preserve">($price, $price)</eg>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-range-expressions" diff="chg" at="A">
               <head>Range Expressions</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-RangeExpr">
                     <lhs>RangeExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>  ("to"  <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-RangeExpr-AdditiveExpr">
                     <lhs>AdditiveExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>  (("+"  |  "-")  <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>
               </scrap>
               <p>
                  <termdef id="dt-range-expression" term="range expression">A 
               <term>range expression</term> is a <termref def="dt-non-trivial"/>
               instance of the production <nt def="doc-xquery40-RangeExpr">RangeExpr<!--$spec = xquery40--></nt>. A range expression
               is used to construct a sequence of 
               integers.</termdef>
               </p>
               <p>Each of the operands is coerced to the required
               type <code nobreak="false">xs:integer?</code> using the <termref def="dt-coercion-rules"/>.
               If either operand is the empty sequence, or if the integer derived from the first operand is greater 
               than the integer derived from the second operand, the result of the range expression is the empty 
               sequence. If the two operands convert to the same integer, the result of the range expression 
               is that integer. Otherwise, the result is a sequence containing the two integer operands and
               every integer between the two operands, in increasing order. </p>
               <p>The following examples illustrate the semantics:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">1 to 4</code> returns the sequence <code nobreak="false">1, 2, 3, 4</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">10 to 10</code> returns the <termref def="dt-singleton"/> sequence <code nobreak="false">10</code>
                     </p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">10 to 1</code> returns the empty sequence</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">-13 to -10</code> returns the sequence <code nobreak="false">-13, -12, -11, -10</code>
                     </p>
                  </item>
               </ulist>
               <p>More formally, a <termref def="dt-range-expression"/> is evaluated as follows:</p>
               <olist>
                  <item>
                     <p>Each of the operands of the <code nobreak="false">to</code> operator is converted as though it was an argument of a function
                  with the expected parameter type <code nobreak="false">xs:integer?</code>.</p>
                  </item>
                  <item>
                     <p>If either operand is the empty sequence, or if the integer derived from the first operand is greater
                  than the integer derived from the second operand, the result of the range expression is the empty sequence.</p>
                  </item>
                  <item>
                     <p>If the two operands convert to the same integer, the result of the range expression is that integer.</p>
                  </item>
                  <item>
                     <p>Otherwise, the result is a sequence containing the two integer operands and every integer between the 
                  two operands, in increasing order.</p>
                  </item>
               </olist>
               <p>The following examples illustrate the use of 
               <termref def="dt-range-expression">range expressions</termref>.</p>
               <example>
                  <p>This example uses a range expression as one operand in constructing a sequence. 
                  It evaluates to the sequence <code nobreak="false">10, 1, 2, 3, 4</code>.</p>
                  <eg role="parse-test" xml:space="preserve">(10, 1 to 4)</eg>
                  <p>This example selects the first four items from an input sequence:</p>
                  <eg role="parse-test" xml:space="preserve">$input[1 to 4]</eg>
                  <p>This example returns the sequence <code nobreak="false">(0, 0.1, 0.2, 0.3, 0.5)</code>:</p>
                  <eg role="parse-test" xml:space="preserve">$x = (1 to 5) ! . * 0.1</eg>
                  <p>This example constructs a sequence of length one containing the single integer 10.</p>
                  <eg role="parse-test" xml:space="preserve">10 to 10</eg>
                  <p>The result of this example is a sequence of length zero.</p>
                  <eg role="parse-test" xml:space="preserve">15 to 10</eg>
                  <p>This example uses the <function>fn:reverse</function> function to construct a sequence of six integers in decreasing order. 
                  It evaluates to the sequence 15, 14, 13, 12, 11, 10.</p>
                  <eg role="parse-test" xml:space="preserve">reverse(10 to 15)</eg>
               </example>
               <note>
                  <p>To construct a sequence of integers based on steps other than 1, use the <function>fn:slice</function>
               function, as defined in <xspecref spec="FO31" ref="general-seq-funcs"/>.</p>
               </note>
            </div3>
            <div3 id="combining_seq">
               <head>Combining GNode Sequences</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-UnionExpr">
                     <lhs>UnionExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-IntersectExceptExpr">IntersectExceptExpr<!--$idref_lang_part = xquery40- --></nt>  (("union"  |  "|")  <nt def="prod-xquery40-IntersectExceptExpr">IntersectExceptExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="doc-xquery40-UnionExpr-IntersectExceptExpr">
                     <lhs>IntersectExceptExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-InstanceofExpr">InstanceofExpr<!--$idref_lang_part = xquery40- --></nt>  (("intersect"  |  "except")  <nt def="prod-xquery40-InstanceofExpr">InstanceofExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="doc-xquery40-UnionExpr-InstanceofExpr">
                     <lhs>InstanceofExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TreatExpr">TreatExpr<!--$idref_lang_part = xquery40- --></nt>  ("instance"  "of"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>
               </scrap>
               <p>XQuery 4.0 provides the following operators for combining sequences of
<termref def="dt-GNode">GNodes</termref>:</p>
               <ulist>
                  <item>
                     <p>The <code nobreak="false">union</code> and <code nobreak="false">|</code> operators are equivalent. They take two node sequences as operands and
return a sequence containing all the GNodes that occur in either of the
operands.</p>
                  </item>
                  <item>
                     <p>The <code nobreak="false">intersect</code> operator takes two GNodes sequences as operands and returns a sequence
containing all the GNodes that occur in both operands.</p>
                  </item>
                  <item>
                     <p>The <code nobreak="false">except</code> operator takes two node sequences as operands and returns a sequence
containing all the GNodes that occur in the first operand but not in the second
operand.</p>
                  </item>
               </ulist>
               <p>All these operators eliminate duplicate GNodes from their result sequences based on GNode identity. 
               The resulting sequence is returned in <termref def="dt-document-order">document order</termref>.
            </p>
               <p>If an operand
of <code nobreak="false">union</code>, <code nobreak="false">intersect</code>, or <code nobreak="false">except</code> contains an item that is not a <termref def="dt-GNode"/>, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
               <p>
If an <nt def="prod-xquery40-IntersectExceptExpr">IntersectExceptExpr<!--$spec = xquery40--></nt> contains more than two 
               <nt def="doc-xquery40-InstanceofExpr">InstanceofExpr<!--$spec = xquery40--></nt> operands,
they are evaluated from left to right.
With a <code nobreak="false">UnionExpr</code>, it makes no difference how operands are grouped,
the results are the same.
</p>
               <example>
                  <p>Here are some examples of expressions that combine sequences. 
                  Assume the existence of three element nodes that we will refer to by symbolic names A, B, and C. 
                  Assume that the variables <code nobreak="false">$seq1</code>, <code nobreak="false">$seq2</code>  and <code nobreak="false">$seq3</code> 
                  are bound to the following sequences of these nodes:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">$seq1</code> is bound to (A, B)</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$seq2</code> is bound to (A, B)</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$seq3</code> is bound to (B, C)</p>
                     </item>
                  </ulist>
                  <p>Then: </p>
                  <ulist>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$seq1 union $seq2</code>  evaluates to the sequence (A, B). </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$seq2 union $seq3</code>   evaluates to the sequence (A, B, C). </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$seq1 intersect $seq2</code>  evaluates to the sequence (A, B). </p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$seq2 intersect $seq3</code>  evaluates to the sequence containing B only.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$seq1 except $seq2</code>   evaluates to the empty sequence.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">$seq2 except $seq3</code>  evaluates to the sequence containing A only.</p>
                     </item>
                  </ulist>
               </example>
               <p>The following example demonstrates the use of the <code nobreak="false">except</code> operator
            with JNodes:</p>
               <eg xml:space="preserve">let $m := jtree($map)
for $e in $m/child::* except $m/child::xx 
return ...</eg>
               <note>
                  <p>Because the <function>fn:jtree</function> creates a new JTree root,
            calling it twice potentially creates two different trees, in which the JNodes have
            different identity. The expression <code nobreak="false">$map/child::* except $map/child::xx</code>
            might therefore have the wrong effect, because JNodes in two different trees 
            are being compared. For more details see the specification of the
            <function>fn:jtree</function> function.</p>
               </note>
               <p>In addition to the sequence operators described here, see <xspecref spec="FO40" ref="sequence-functions"/> for functions defined on sequences.
</p>
            </div3>
         </div2>
         <div2 id="id-arithmetic">
            <head>Arithmetic Expressions</head>
            <changes>
               <change>
               The symbols <code nobreak="false">×</code> and <code nobreak="false">÷</code> can be used for multiplication and division.
            </change>
            </changes>
            <p>XQuery 4.0 provides binary arithmetic operators for addition, subtraction,
multiplication, division, and modulus:</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-AdditiveExpr">
                  <lhs>AdditiveExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>  (("+"  |  "-")  <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-AdditiveExpr-MultiplicativeExpr">
                  <lhs>MultiplicativeExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-UnionExpr">UnionExpr<!--$idref_lang_part = xquery40- --></nt>  (("*"  |  "×"  |  "div"  |  "÷"  |  "idiv"  |  "mod")  <nt def="prod-xquery40-UnionExpr">UnionExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-AdditiveExpr-UnionExpr">
                  <lhs>UnionExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-IntersectExceptExpr">IntersectExceptExpr<!--$idref_lang_part = xquery40- --></nt>  (("union"  |  "|")  <nt def="prod-xquery40-IntersectExceptExpr">IntersectExceptExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>
            </scrap>
            <p>In addition, unary operators are provided for addition and subtraction:</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-UnaryExpr">
                  <lhs>UnaryExpr</lhs>
                  <rhs>("-"  |  "+")*  <nt def="prod-xquery40-ValueExpr">ValueExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-UnaryExpr-ValueExpr">
                  <lhs>ValueExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ValidateExpr">ValidateExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ExtensionExpr">ExtensionExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SimpleMapExpr">SimpleMapExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-UnaryExpr-ValidateExpr">
                  <lhs>ValidateExpr</lhs>
                  <rhs>"validate"  (<nt def="prod-xquery40-ValidationMode">ValidationMode<!--$idref_lang_part = xquery40- --></nt>  |  ("type"  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>))?  "{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-UnaryExpr-ExtensionExpr">
                  <lhs>ExtensionExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Pragma">Pragma<!--$idref_lang_part = xquery40- --></nt>+  "{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-UnaryExpr-SimpleMapExpr">
                  <lhs>SimpleMapExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PathExpr">PathExpr<!--$idref_lang_part = xquery40- --></nt>  ("!"  <nt def="prod-xquery40-PathExpr">PathExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>
            </scrap>
            <p>A subtraction operator must be preceded by whitespace if
it could otherwise be interpreted as part of the previous token. For
example, <code role="parse-test" nobreak="false">a-b</code> will be interpreted as a
name, but <code role="parse-test" nobreak="false">a - b</code> and <code role="parse-test" nobreak="false">a -b</code> will be interpreted as arithmetic expressions. (See <specref ref="whitespace-rules"/> for further details on whitespace handling.)</p>
            <p diff="add" at="2023-05-02">The arithmetic operator symbols <code nobreak="false">*</code> and <char>U+00D7</char> are interchangeable,
         and denote multiplication.</p>
            <p diff="add" at="2023-05-02">The arithmetic operator symbols <code nobreak="false">div</code> and <char>U+00F7</char> are interchangeable,
            and denote division.</p>
            <p>
If an <code nobreak="false">AdditiveExpr</code> contains more than two <code nobreak="false">MultiplicativeExprs</code>,
they are grouped from left to right. So, for instance,
<eg role="parse-test" xml:space="preserve">A - B + C - D</eg>
is equivalent to
<eg role="parse-test" xml:space="preserve">((A - B) + C) - D</eg>
Similarly, the operands of a <code nobreak="false">MultiplicativeExpr</code> are grouped from left to right.
</p>
            <p>The first step in evaluating an arithmetic expression is to evaluate its operand (for
            a unary operator) or operands (for a binary operator). 
            The order in which the operands are evaluated is <termref def="dt-implementation-dependent">implementation-dependent</termref>.</p>
            <p>
               <phrase role="xquery">Each</phrase> operand is evaluated by applying the following steps, in order:</p>
            <olist>
               <item>
                  <p>
                     <termref def="dt-atomization">Atomization</termref> is applied to the operand. The result of this
    operation is called the <term>atomized operand</term>.</p>
               </item>
               <item>
                  <p>If the atomized operand is the empty sequence, the result of
    the arithmetic expression is the empty sequence, and the implementation
    need not evaluate the other operand or apply the operator. However,
    an implementation may choose to evaluate the other operand in order
    to determine whether it raises an error.</p>
               </item>
               <item>
                  <p> If the atomized operand is a sequence of
length greater than one, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
               </item>
               <item>
                  <p>If the atomized operand is of type <code nobreak="false">xs:untypedAtomic</code>, it is cast to  <code nobreak="false">xs:double</code>. If
the cast fails, a <termref def="dt-dynamic-error">dynamic
error</termref> is raised. <xerrorref spec="FO40" class="RG" code="0001"/>
                  </p>
               </item>
            </olist>
            <p>If, after this process, both operands of a binary arithmetic operator
            are instances of <code nobreak="false">xs:numeric</code>
         but have different primitive types, they are coerced to a common type by applying
         the following rules:</p>
            <olist>
               <item>
                  <p>If either of the items is of type <code nobreak="false">xs:double</code>, then 
            both the values are cast to type <code nobreak="false">xs:double</code>.</p>
               </item>
               <item>
                  <p>Otherwise, if either of the items is of type <code nobreak="false">xs:float</code>, then 
              both the values are cast to type <code nobreak="false">xs:float</code>.</p>
               </item>
               <item>
                  <p>Otherwise, no casting takes place: the values remain as <code nobreak="false">xs:decimal</code>.</p>
               </item>
            </olist>
            <p>After this preparation, the arithmetic expression is evaluated by applying the appropriate
         function listed in the table below. The definitions of these functions are found in <bibref ref="xpath-functions-40"/>.</p>
            <table border="1" role="small">
               <caption>Unary Arithmetic Operators</caption>
               <thead>
                  <tr>
                     <th rowspan="1" colspan="1">Expression</th>
                     <th rowspan="1" colspan="1">Type of A</th>
                     <th rowspan="1" colspan="1">Function</th>
                     <th rowspan="1" colspan="1">Result type</th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <td rowspan="1" colspan="1">+ A</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-unary-plus</function>
                        <code nobreak="false">(A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">- A</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-unary-minus</function>
                        <code nobreak="false">(A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                  </tr>
               </tbody>
            </table>
            <table border="1" role="small">
               <caption>Binary Arithmetic Operators</caption>
               <tbody>
                  <tr>
                     <th rowspan="1" colspan="1">Expression</th>
                     <th rowspan="1" colspan="1">Type of A</th>
                     <th rowspan="1" colspan="1">Type of B</th>
                     <th rowspan="1" colspan="1">Function</th>
                     <th rowspan="1" colspan="1">Result type</th>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-add</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-yearMonthDuration-to-date</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:date</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-yearMonthDuration-to-date</function>
                        <code nobreak="false">(B, A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:date</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-dayTimeDuration-to-date</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:date</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-dayTimeDuration-to-date</function>
                        <code nobreak="false">(B, A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:date</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:time</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-dayTimeDuration-to-time</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:time</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:time</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-dayTimeDuration-to-time</function>
                        <code nobreak="false">(B, A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:time</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-yearMonthDuration-to-dateTime</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-yearMonthDuration-to-dateTime</function>
                        <code nobreak="false">(B, A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-dayTimeDuration-to-dateTime</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-dayTimeDuration-to-dateTime</function>
                        <code nobreak="false">(B, A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-yearMonthDurations</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A + B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:add-dayTimeDurations</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-subtract</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-dates</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-yearMonthDuration-from-date</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:date</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:date</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-dayTimeDuration-from-date</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:date</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:time</td>
                     <td rowspan="1" colspan="1">xs:time</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-times</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:time</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-dayTimeDuration-from-time</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:time</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-dateTimes</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-yearMonthDuration-from-dateTime</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-dayTimeDuration-from-dateTime</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dateTime</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-yearMonthDurations</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A - B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:subtract-dayTimeDurations</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A * B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-multiply</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A * B</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:multiply-yearMonthDuration</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A * B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:multiply-yearMonthDuration</function>
                        <code nobreak="false">(B, A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A * B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:multiply-dayTimeDuration</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A * B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:multiply-dayTimeDuration</function>
                        <code nobreak="false">(B, A)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A idiv B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-integer-divide</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:integer</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A div B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-divide</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">numeric; but xs:decimal if both operands are xs:integer</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A div B</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:divide-yearMonthDuration</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A div B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:divide-dayTimeDuration</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A div B</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">xs:yearMonthDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:divide-yearMonthDuration-by-yearMonthDuration</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:decimal</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A div B</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">xs:dayTimeDuration</td>
                     <td rowspan="1" colspan="1">
                        <function>op:divide-dayTimeDuration-by-dayTimeDuration</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:decimal</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">A mod B</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                     <td rowspan="1" colspan="1">
                        <function>op:numeric-mod</function>
                        <code nobreak="false">(A, B)</code>
                     </td>
                     <td rowspan="1" colspan="1">xs:numeric</td>
                  </tr>
               </tbody>
            </table>
            <note>
               <p>The operator symbol <code nobreak="false">×</code> is a synonym of <code nobreak="false">*</code>, while <code nobreak="false">÷</code> is
a synonym of <code nobreak="false">div</code>.</p>
            </note>
            <p>If there is no entry in the table for the combination of operator and operands,
    then a <termref def="dt-type-error"/> is raised <errorref class="TY" code="0004"/>.</p>
            <p>Errors may also occur during coercion of the operands, or during evaluation of the
 identified function (for example, an error
might result from dividing by zero).</p>
            <note>
               <p>XQuery 4.0 provides three division operators:</p>
               <ulist>
                  <item>
                     <p>The <code nobreak="false">div</code> and <code nobreak="false">÷</code> operators are synonyms, and implement
               numeric division as well as division of duration values; the semantics are defined in
               <xspecref spec="FO40" ref="func-numeric-divide"/>
                     </p>
                  </item>
                  <item>
                     <p>The <code nobreak="false">idiv</code> operator implements integer division; the semantics are defined
               in <xspecref spec="FO40" ref="func-numeric-integer-divide"/>
                     </p>
                  </item>
               </ulist>
            </note>
            <p>Here are some examples of arithmetic expressions:</p>
            <ulist>
               <item>
                  <p>The first expression below returns the <code nobreak="false">xs:decimal</code> value <code role="parse-test" nobreak="false">-1.5</code>, and the second expression returns the <code nobreak="false">xs:integer</code> value <code role="parse-test" nobreak="false">-1</code>:</p>
                  <eg role="parse-test" xml:space="preserve">-3 div 2
-3 idiv 2</eg>
               </item>
               <item>
                  <p>Subtraction of two date values results in a value of type <code nobreak="false">xs:dayTimeDuration</code>:</p>
                  <eg role="parse-test" xml:space="preserve">$emp/hiredate - $emp/birthdate</eg>
               </item>
               <item>
                  <p>This example illustrates the difference between a subtraction operator and a
hyphen:</p>
                  <eg role="parse-test" xml:space="preserve">$unit-price - $unit-discount</eg>
               </item>
               <item>
                  <p>Unary operators have higher precedence than binary operators (other than <code nobreak="false">!</code>, <code nobreak="false">/</code>, and <code nobreak="false">[]</code>), subject of
course to the use of parentheses. Therefore, the following two examples have different meanings:</p>
                  <eg xml:space="preserve">-$bellcost + $whistlecost
-($bellcost + $whistlecost)</eg>
               </item>
            </ulist>
            <note>
               <p id="note-consecutive-unary-ops">Multiple consecutive unary arithmetic operators are permitted (though not useful).</p>
            </note>
            <note>
               <p>Negation is not the same as subtraction from zero: if <code nobreak="false">$x</code> is positive zero,
            then <code nobreak="false">-$x</code> returns negative zero, wheras <code nobreak="false">0 - $x</code> returns positive zero.</p>
            </note>
         </div2>
         <div2 id="id-string-expr">
            <head>String Expressions</head>
            <p>This section describes several ways of constructing strings.</p>
            <div3 id="id-string-concat-expr">
               <head>String Concatenation Expressions</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-StringConcatExpr">
                     <lhs>StringConcatExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-RangeExpr">RangeExpr<!--$idref_lang_part = xquery40- --></nt>  ("||"  <nt def="prod-xquery40-RangeExpr">RangeExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="doc-xquery40-StringConcatExpr-RangeExpr">
                     <lhs>RangeExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>  ("to"  <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>
               </scrap>
               <p>String concatenation expressions allow the string representations of values to be
               concatenated. In XQuery 4.0, <code nobreak="false">$a || $b</code> is equivalent to
               <code nobreak="false">fn:concat($a, $b)</code>.
               The following expression evaluates to the string <code nobreak="false">concatenate</code>:</p>
               <eg xml:space="preserve">() || "con" || ("cat", "enate")</eg>
            </div3>
            <div3 id="id-string-templates" diff="add" at="2023-01-29">
               <head>String Templates</head>
               <changes>
                  <change issue="58" PR="324" date="2023-01-29">
                  String templates provide a new way of constructing strings: for example <code nobreak="false">`{$greeting}, {$planet}!`</code>
                  is equivalent to <code nobreak="false">$greeting || ', ' || $planet || '!'</code>
                  </change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-StringTemplate">
                     <lhs>StringTemplate</lhs>
                     <rhs>"`"  (<nt def="prod-xquery40-StringTemplateFixedPart">StringTemplateFixedPart<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-StringTemplateVariablePart">StringTemplateVariablePart<!--$idref_lang_part = xquery40- --></nt>)*  "`"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-StringTemplate-StringTemplateFixedPart">
                     <lhs>StringTemplateFixedPart</lhs>
                     <rhs>((<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - ('{' | '}' | '`'))  |  "{{"  |  "}}"  |  "``")+</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-StringTemplate-Char">
                     <lhs>Char</lhs>
                     <rhs>
                        <xnt ref="NT-Char" spec="XML">[http://www.w3.org/TR/REC-xml#NT-Char]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-StringTemplate-StringTemplateVariablePart">
                     <lhs>StringTemplateVariablePart</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-StringTemplate-EnclosedExpr">
                     <lhs>EnclosedExpr</lhs>
                     <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                  </prod>
               </scrap>
               <p>String templates provide an alternative way of constructing strings. For example,
            the expression <code nobreak="false">`Pi is { round(math:pi(), 4) }`</code> returns the string <code nobreak="false">"Pi is 3.1416"</code>.</p>
               <p>A string template starts and ends with <char>U+0060</char>, popularly known as a back-tick. Between
               the back-ticks is a string consisting of an sequence of fixed parts and
               variable parts:</p>
               <ulist>
                  <item>
                     <p>A variable part consists of an optional XPath expression enclosed in curly brackets (<code nobreak="false">{}</code>):
                  more specifically, a string conforming 
                  to the XPath production <code nobreak="false">Expr?</code>.</p>
                     <note>
                        <p>An expression within a variable part may contain an unescaped <char>U+007B</char> 
                        or <char>U+007D</char> within
                        a <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$spec = xquery40--></nt> or within
                        a comment.</p>
                        <p>The fact that the expression is optional means that the
                        string contained between the curly brackets may be zero-length, may comprise whitespace
                        only, or may contain XPath comments. The effective value in this case is a zero-length
                        string, which is equivalent to omitting the variable part entirely, together with its 
                        curly-bracket delimiters. </p>
                     </note>
                  </item>
                  <item>
                     <p>A fixed part may contain any characters, except that:</p>
                     <ulist>
                        <item>
                           <p>The character <char>U+007B</char>
                              <rfc2119>must</rfc2119>
                        be written as <code nobreak="false">{{</code>.</p>
                        </item>
                        <item>
                           <p>The character <char>U+007D</char>
                              <rfc2119>must</rfc2119> be
                        written as <code nobreak="false">}}</code>.</p>
                        </item>
                        <item>
                           <p>The character <char>U+0060</char>
                              <rfc2119>must</rfc2119> be
                        written as <code nobreak="false">``</code>.</p>
                        </item>
                     </ulist>
                     <p>Following the principles of the “longest token” rule, any occurrence
                  of <code nobreak="false">{{</code> within the fixed part is interpreted as an escaped left
                  curly bracket. This means that the enclosed expression must not start with
                  <char>U+007B</char>: if this is required, the two left curly brackets can
                  be separated by whitespace. For example the string template
                     <code nobreak="false">`{{"key":"{ {1:"yes", 0:"no"}?$condition}"}}`</code>
                     evaluates to the string <code nobreak="false">{"key":"yes"}</code> or <code nobreak="false">{"key":"no"}</code>
                     depending on the value of <code nobreak="false">$condition</code>.</p>
                     <p>By contrast, if the enclosed expression ends with <char>U+007D</char>,
                  this can be immediately followed by the closing <char>U+007D</char>
                  delimiter without intervening whitespace.</p>
                  </item>
               </ulist>
               <p>
               The result of evaluating a
                  string template is the string obtained by concatenating the expansions of the fixed
               and variable parts:</p>
               <ulist>
                  <item>
                     <p>The expansion of a fixed part is obtained by replacing any double curly
                     brackets (<code nobreak="false">{{</code> or <code nobreak="false">}}</code>) by the corresponding single curly
                     bracket, and replacing doubled back-ticks (<code nobreak="false">``</code>) by a single back-tick.</p>
                  </item>
                  <item>
                     <p>The expansion of a variable part containing an expression is as follows:</p>
                     <olist>
                        <item>
                           <p>
                              <termref def="dt-atomization">Atomization</termref> is applied to the value of the enclosed expression, 
                           converting it to a sequence of atomic items.</p>
                        </item>
                        <item>
                           <p>If the result of atomization is the empty sequence, the result 
                           is the zero-length string. Otherwise, each atomic item in the 
                           atomized sequence is cast into a string.</p>
                        </item>
                        <item>
                           <p>The individual strings resulting from the previous step are 
                           merged into a single string by concatenating them with a 
                           single space character between each pair.</p>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>The expansion of the empty variable part (one that contains no expression) is a zero-length string.</p>
                  </item>
               </ulist>
               <p>For example:</p>
               <eg role="parse-test" xml:space="preserve">let $greeting := "Hello", $planet := "Mars"
return `{ $greeting }, { $planet }!`</eg>
               <p>returns <code nobreak="false">"Hello, Mars!"</code>.</p>
               <p>The expression:</p>
               <eg role="parse-test" xml:space="preserve">let $long-months := (1, 3, 5, 7, 8, 10, 12)
return `The months with 31 days are: { $long-months }.`</eg>
               <p>returns <code nobreak="false">"The months with 31 days are: 1 3 5 7 8 10 12."</code>.</p>
               <note>
                  <p>The rules for processing an enclosed expression are identical to the rules for attributes in
               XQuery direct element constructors. These rules differ slightly from the rules in XSLT
               attribute value templates, where adjacent text nodes are concatenated with no separator,
               prior to atomization.</p>
               </note>
               <note>
                  <p>A string template containing no variable parts is effectively just another
                  way of writing a string literal: <code nobreak="false">"Goethe"</code>, <code nobreak="false">'Goethe'</code>, and <code nobreak="false">`Goethe`</code>
               are interchangeable. This means that back-ticks can sometimes be a useful way of delimiting a string
               that contains both single and double quotes: <code nobreak="false">`He said: "I didn't."`</code>.</p>
                  <p>It is sometimes useful to use string templates in conjunction with the <function>fn:char</function> function
                  to build strings containing special characters, for example <code nobreak="false">`Chapter{ fn:char("nbsp") }{ $chapNr }`</code>.</p>
               </note>
               <note>
                  <p>String literals containing an ampersand behave differently between XPath and XQuery: in XPath 
               (unless first expanded by an XML parser) the string literal <code nobreak="false">"Bacon &amp; Eggs"</code> 
               represents a string containing an ampersand, while in XQuery
               it is an error, because an ampersand is taken as introducing a character reference. This difference
               does not arise for string templates, since neither XPath nor XQuery recognizes entity or character references
               in a string template.
               This means that back-tick delimited strings (such as <code nobreak="false">`Bacon &amp; Eggs`</code>) 
                  may be useful in contexts where an XPath expression
               is required to have the same effect whether it is evaluated using an XPath or an XQuery processor.</p>
               </note>
               <p>In XQuery, the token <code nobreak="false">``[</code> is recognized as the start of a 
               <termref def="dt-string-constructor" role="xquery"/>,
            under the “longest token” rule (see <specref ref="lexical-structure"/>). This means that the construct
               <code nobreak="false">``[1]</code> is not recognized as a <nt def="doc-xquery40-StringTemplate">StringTemplate<!--$spec = xquery40--></nt> followed by a predicate. 
                In the unlikely event that an empty <nt def="doc-xquery40-StringTemplate">StringTemplate<!--$spec = xquery40--></nt>
            followed by a predicate is wanted, whitespace or parentheses can be used to avoid the tokenization problem.</p>
            </div3>
            <div3 id="id-string-constructors" role="xquery">
               <head>String Constructors</head>
               <p>
                  <termdef term="string constructor" id="dt-string-constructor">A
                  <term>string constructor</term> is an instance of the production
                  <nt def="doc-xquery40-StringConstructor">StringConstructor<!--$spec = xquery40--></nt>: it
                  is an expression that creates a string from literal text and interpolated subexpressions.
               </termdef>
               </p>
               <p>The syntax of a string constructor is convenient for generating
               JSON, JavaScript, CSS, SPARQL, XQuery, XPath, or other languages that
               use curly brackets, quotation marks, or other strings that are
               delimiters in XQuery 4.0.</p>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-StringConstructor">
                     <lhs>StringConstructor</lhs>
                     <rhs>"``["  <nt def="prod-xquery40-StringConstructorContent">StringConstructorContent<!--$idref_lang_part = xquery40- --></nt>  "]``"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-StringConstructor-StringConstructorContent">
                     <lhs>StringConstructorContent</lhs>
                     <rhs>
                        <nt def="prod-xquery40-StringConstructorChars">StringConstructorChars<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-StringInterpolation">StringInterpolation<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-StringConstructorChars">StringConstructorChars<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-StringConstructor-StringConstructorChars">
                     <lhs>StringConstructorChars</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* ('`{' | ']``') Char*))</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-StringConstructor-Char">
                     <lhs>Char</lhs>
                     <rhs>
                        <xnt ref="NT-Char" spec="XML">[http://www.w3.org/TR/REC-xml#NT-Char]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-StringConstructor-StringInterpolation">
                     <lhs>StringInterpolation</lhs>
                     <rhs>"`{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}`"</rhs>
                  </prod>

                  <prod id="doc-xquery40-StringConstructor-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>
               </scrap>
               <note diff="add" at="2023-01-29">
                  <p>String templates (see <specref ref="id-string-templates"/>) and string constructors
               have overlapping functionality. String constructors were introduced in XQuery 3.1,
               and are not available in XPath; string templates are new in XQuery 4.0 and XPath 4.0.
               String constructors were designed specifically for convenience when generating
               code in languages that use curly brackets, but with experience, they have been found to
               be somewhat unwieldy for simpler applications; this motivated the introduction of
               a simpler syntax in 4.0.</p>
               </note>
               <p>In a <nt def="doc-xquery40-StringConstructor">string constructor<!--$spec = xquery40--></nt>, adjacent
               <nt def="prod-xquery40-StringConstructorChars">string constructor characters<!--$spec = xquery40--></nt>
               are treated as literal text. Line endings are processed as elsewhere
               in XQuery; no other processing is performed on this text. 
               
               To evaluate a string constructor, each sequence of adjacent string
               constructor characters is converted to a string containing the same
               characters, and each <nt def="prod-xquery40-StringInterpolation">string
                  constructor interpolation<!--$spec = xquery40--></nt>
                  <code nobreak="false">$i</code> is evaluated, then
               converted to a string using the expression <code role="parse-test" nobreak="false">string-join($i, ' ')</code>.  
               
               A string constructor interpolation that does not contain an expression (<code nobreak="false">`{ }`</code>) is ignored. 
               
               The strings
               created from string constructor characters and the strings created
               from string constructor interpolations are then concatenated, in
               order.</p>
               <p>For instance, the following expression:</p>
               <eg role="parse-test" xml:space="preserve">for $s in ("one", "two", "red", "blue")
return ``[`{ $s }` fish]``
</eg>
               <p>evaluates to the sequence  <code nobreak="false">("one fish", "two fish", "red fish", "blue fish")</code>.</p>
               <note>
                  <p>Character entities are not expanded in string constructor
                  content.  Thus, <code nobreak="false">``[&amp;lt;]``</code> evaluates to the string
                  <code nobreak="false">"&amp;lt;"</code>, not the string
                  <code nobreak="false">"&lt;"</code>.</p>
               </note>
               <p>Interpolations can contain string constructors. For instance, consider the following expression:</p>
               <eg xml:space="preserve">``[`{ $i, ``[literal text]``, $j, ``[more literal text]`` }`]``</eg>
               <p>Assuming the values <code nobreak="false">$i := 1</code> and <code nobreak="false">$j := 2</code>, this evaluates to the string <code nobreak="false">"1 literal text 2 more literal text"</code>.</p>
               <p>The following examples are based on an example taken from the documentation of <bibref ref="Moustache"/>, a JavaScript template library. Each function takes a map, containing values like these:</p>
               <eg xml:space="preserve">{
  "name": "Chris",
  "value": 10000,
  "taxed_value": 10000 - (10000 * 0.4),
  "in_ca": true
}</eg>
               <p>This function creates a simple string.</p>
               <eg xml:space="preserve">declare function local:prize-message($a) as xs:string {
  ``[Hello `{ $a?name }`
You have just won `{ $a?value }` dollars!
`{ 
   if ($a?in_ca) 
   then ``[Well, `{ $a?taxed_value }` dollars, after taxes.]``
   else ""
}`]``
};</eg>
               <p>This is the output of the above function :</p>
               <eg xml:space="preserve">Hello Chris
You have just won 10000 dollars!
Well, 6000 dollars, after taxes.</eg>
               <p>This function creates a similar string in HTML syntax.</p>
               <eg xml:space="preserve">declare function local:prize-message($a) as xs:string {
  ``[&lt;div&gt;
  &lt;h1&gt;Hello `{ $a?name }`&lt;/h1&gt;
  &lt;p&gt;You have just won `{ $a?value }` dollars!&lt;/p&gt;
    `{ 
      if ($a?in_ca) 
      then ``[  &lt;p&gt;Well, `{ $a?taxed_value }` dollars, after taxes.&lt;/p&gt; ]``
      else ""
    }`
&lt;/div&gt;]``
};</eg>
               <p>This is the output of the above function :</p>
               <eg xml:space="preserve">&lt;div&gt;
  &lt;h1&gt;Hello Chris&lt;/h1&gt;
  &lt;p&gt;You have just won 10000 dollars!&lt;/p&gt;
  &lt;p&gt;Well, 6000 dollars, after taxes.&lt;/p&gt; 
&lt;/div&gt;</eg>
               <p>This function creates a similar string in JSON syntax.</p>
               <eg xml:space="preserve">
declare function local:prize-message($a) as xs:string {
  ``[{ 
  "name": `{ $a?name }`
  "value": `{ $a?value }`
  `{
  if ($a?in_ca) 
  then 
  ``[, 
  "taxed_value": `{ $a?taxed_value }`]``  
  else ""
  }`
}]`` 
};</eg>
               <p>This is the output of the above function :</p>
               <eg xml:space="preserve">{ 
  "name": "Chris",
  "value": 10000,
  "taxed_value": 6000
}</eg>
               <p>Within an enclosed expression, the handling of expressions that start with <char>U+007B</char> or that
            end with <char>U+007D</char> is the same as for <specref ref="id-string-templates"/>.</p>
            </div3>
         </div2>
         <div2 id="id-comparisons">
            <head>Comparison Expressions</head>
            <p>Comparison expressions allow two values to be compared. XQuery 4.0 provides
three kinds of comparison expressions, called value comparisons, general
comparisons, and GNode comparisons.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ComparisonExpr">
                  <lhs>ComparisonExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-OtherwiseExpr">OtherwiseExpr<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-ValueComp">ValueComp<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-GeneralComp">GeneralComp<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NodeComp">NodeComp<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-OtherwiseExpr">OtherwiseExpr<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
               </prod>

               <prod id="doc-xquery40-ComparisonExpr-OtherwiseExpr">
                  <lhs>OtherwiseExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-StringConcatExpr">StringConcatExpr<!--$idref_lang_part = xquery40- --></nt>  ("otherwise"  <nt def="prod-xquery40-StringConcatExpr">StringConcatExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-ComparisonExpr-ValueComp">
                  <lhs>ValueComp</lhs>
                  <rhs>"eq"  |  "ne"  |  "lt"  |  "le"  |  "gt"  |  "ge"</rhs>
               </prod>

               <prod id="doc-xquery40-ComparisonExpr-GeneralComp">
                  <lhs>GeneralComp</lhs>
                  <rhs>"="  |  "!="  |  "&lt;"  |  "&lt;="  |  "&gt;"  |  "&gt;="</rhs>
               </prod>

               <prod id="doc-xquery40-ComparisonExpr-NodeComp">
                  <lhs>NodeComp</lhs>
                  <rhs>"is"  |  "is-not"  |  <nt def="prod-xquery40-NodePrecedes">NodePrecedes<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NodeFollows">NodeFollows<!--$idref_lang_part = xquery40- --></nt>  |  "precedes-or-is"  |  "follows-or-is"</rhs>
               </prod>

               <prod id="doc-xquery40-ComparisonExpr-NodePrecedes">
                  <lhs>NodePrecedes</lhs>
                  <rhs>"&lt;&lt;"  |  "precedes"</rhs>
               </prod>

               <prod id="doc-xquery40-ComparisonExpr-NodeFollows">
                  <lhs>NodeFollows</lhs>
                  <rhs>"&gt;&gt;"  |  "follows"</rhs>
               </prod>
            </scrap>
            <p>For a summary of the differences between different ways of comparing atomic items
         in XQuery 4.0, see <specref ref="id-atomic-comparisons"/>.</p>
            <div3 id="id-value-comparisons">
               <head>Value Comparisons</head>
               <changes>
                  <change issue="986" PR="2218" date="2025-09-29">
                  The rules for value comparisons when comparing values of different types (for example, decimal and double)
                  have changed to be transitive. A decimal value is no longer converted to double, instead the double is converted
                  to a decimal without loss of precision. This may affect compatibility in edge cases involving comparison of
                  values that are numerically very close.
               </change>
                  <change issue="2216" PR="2256" date="2025-12-01">
                  An ordering is now defined for all data types.
               </change>
               </changes>
               <p>The value comparison operators are <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>. 
               Value comparisons are used for comparing single <termref def="dt-atomic-item">atomic items</termref>.</p>
               <p>The first step in evaluating a value comparison is to evaluate its operands. The order in which the operands are evaluated is <termref def="dt-implementation-dependent">implementation-dependent</termref>. Each operand is evaluated by applying the following steps, in order:</p>
               <olist>
                  <item>
                     <p>
                        <termref def="dt-atomization">Atomization</termref> is applied to each  operand. The result of this
    operation is called the <term>atomized operand</term>.</p>
                  </item>
                  <item>
                     <p>If either or both of the atomized operands is the empty sequence, the result of
    the value comparison is the empty sequence, and the implementation
    need not evaluate the other operand or apply the operator. However,
    an implementation may choose to evaluate the other operand and may raise
    an error if evaluation fails.</p>
                  </item>
                  <item>
                     <p> If an atomized operand is a sequence of
length greater than one, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                  </item>
                  <!--<item>
                  <p>If an  atomized operand is of type
  <code>xs:untypedAtomic</code> or <code>xs:anyURI</code>, then it is cast to
  <code>xs:string</code>.</p>
                  
               </item>-->
                  <item>
                     <p>If both operands are instances of <code nobreak="false">xs:numeric</code>, and
                     if either or both of the atomized operands is <code nobreak="false">NaN</code>, then the result is
               <code nobreak="false">false</code> if the operator is <code nobreak="false">eq</code>, <code nobreak="false">lt</code>, <code nobreak="false">gt</code>,
               <code nobreak="false">le</code>, or <code nobreak="false">ge</code>, but <code nobreak="false">true</code> if the operator
               is <code nobreak="false">ne</code>.</p>
                     <note>
                        <p>When an operand is <code nobreak="false">NaN</code>, the effect of a value comparison
               expression differs from the result of the <function>fn:compare</function>
               function.</p>
                     </note>
                  </item>
                  <item>
                     <p>The function <function>fn:compare</function> is then called, supplying
               the two atomized operands as the first two arguments. The collation used
               by <function>fn:compare</function> is the default collation from the static
               context, and the implicit timezone used by the function is the implicit
               timezone from the dynamic context.</p>
                     <note>
                        <p>The effect of this rule is that <code nobreak="false">xs:untypedAtomic</code>
               values (which typically result from atomizing a node) are treated as strings.</p>
                     </note>
                  </item>
                  <item>
                     <p>If <function>fn:compare</function> raises an error (typically because
               the two operands belong to different 
                  <xtermref spec="DM40" ref="dt-type-family">type families</xtermref>),
               then the value comparison fails with that error.</p>
                  </item>
                  <item>
                     <p>The result of the <function>fn:compare</function> function determines
               the result of the value comparison, according to the following table:</p>
                     <table>
                        <caption>Result of a Value Comparison</caption>
                        <thead>
                           <tr>
                              <th rowspan="1" colspan="1">Result of <function>fn:compare</function>
                              </th>
                              <th rowspan="1" colspan="1">
                                 <code nobreak="false">eq</code>
                              </th>
                              <th rowspan="1" colspan="1">
                                 <code nobreak="false">ne</code>
                              </th>
                              <th rowspan="1" colspan="1">
                                 <code nobreak="false">lt</code>
                              </th>
                              <th rowspan="1" colspan="1">
                                 <code nobreak="false">le</code>
                              </th>
                              <th rowspan="1" colspan="1">
                                 <code nobreak="false">gt</code>
                              </th>
                              <th rowspan="1" colspan="1">
                                 <code nobreak="false">ge</code>
                              </th>
                           </tr>
                        </thead>
                        <tbody>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">-1</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">0</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                           </tr>
                           <tr>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">+1</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">false</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                              <td rowspan="1" colspan="1">
                                 <code nobreak="false">true</code>
                              </td>
                           </tr>
                        </tbody>
                     </table>
                  </item>
               </olist>
               <!--<item>
                  <p>Expressions using operators other than <code>eq</code> and <code>lt</code>
                  are rewritten as follows:</p>
                  <slist>
                     <sitem><code>A ne B</code> becomes <code>not(A eq B)</code></sitem>
                     <sitem><code>A le B</code> becomes <code>A lt B or A eq B</code></sitem>
                     <sitem><code>A gt B</code> becomes <code>B lt A</code></sitem>
                     <sitem><code>A ge B</code> becomes <code>B lt A or B eq A</code></sitem>
                  </slist>
               </item>-->
               <!--<item>
                  <p>If the types of the two operands correspond to an entry
                     in the table below, the operator is applied to the
                     operands by applying the appropriate function from the table.</p>
                  
                  <p>If the table contains no entry corresponding to the types of the operands, 
               then a <termref def="dt-type-error"
                  >type error</termref>
is raised <errorref class="TY" code="0004"/>.</p>
               </item>

            </olist>
            
            
           <table border="1" role="small">
<caption>Value Comparison Operators</caption>
<tbody>

<tr>
<th>Expression</th>
<th>Type(A)</th>
<th>Type(B)</th>
<th>Function</th>
</tr>



<tr><td>A eq B</td><td>xs:numeric</td><td>xs:numeric</td>
   <td><function>op:numeric-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>xs:boolean</td><td>xs:boolean</td><td><function>op:boolean-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>xs:string</td><td>xs:string</td><td>
   <code>fn:atomic-equal(fn:compare(A, B), 0)</code></td></tr>

<tr><td>A eq B</td><td>xs:date</td><td>xs:date</td><td><function>op:date-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>xs:time</td><td>xs:time</td><td><function>op:time-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>xs:dateTime</td><td>xs:dateTime</td><td><function>op:dateTime-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>xs:duration</td><td>xs:duration</td><td><function>op:duration-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>xs:gYear</td><td>xs:gYear</td><td><function>op:gYear-equal</function><code>(A, B)</code></td></tr>
<tr><td>A eq B</td><td>xs:gYearMonth</td><td>xs:gYearMonth</td><td><function>op:gYearMonth-equal</function><code>(A, B)</code></td></tr>
<tr><td>A eq B</td><td>xs:gMonth</td><td>xs:gMonth</td><td><function>op:gMonth-equal</function><code>(A, B)</code></td></tr>
<tr><td>A eq B</td><td>xs:gMonthDay</td><td>xs:gMonthDay</td><td><function>op:gMonthDay-equal</function><code>(A, B)</code></td></tr>
<tr><td>A eq B</td><td>xs:gDay</td><td>xs:gDay</td><td><function>op:gDay-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>(xs:hexBinary | xs:base64Binary)</td><td>(xs:hexBinary | xs:base64Binary)</td><td><function>op:binary-equal</function><code>(A, B)</code></td></tr>


<tr><td>A eq B</td><td>xs:QName</td><td>xs:QName</td><td><function>op:QName-equal</function><code>(A, B)</code></td></tr>

<tr><td>A eq B</td><td>xs:NOTATION</td><td>xs:NOTATION</td><td><function>op:NOTATION-equal</function><code>(A, B)</code></td></tr>




<tr><td>A lt B</td><td>xs:numeric</td><td>xs:numeric</td>
   <td><function>op:numeric-less-than</function><code>(A, B)</code></td></tr>

<tr><td>A lt B</td><td>xs:boolean</td><td>xs:boolean</td><td><function>op:boolean-less-than</function><code>(A, B)</code></td></tr>

<tr><td>A lt B</td><td>xs:string</td><td>xs:string</td><td>
   <code>fn:atomic-equal(fn:compare(A, B), -1)</code></td></tr>

<tr><td>A lt B</td><td>xs:date</td><td>xs:date</td><td><function>op:date-less-than</function><code>(A, B)</code></td></tr>

<tr><td>A lt B</td><td>xs:time</td><td>xs:time</td><td><function>op:time-less-than</function><code>(A, B)</code></td></tr>

<tr><td>A lt B</td><td>xs:dateTime</td><td>xs:dateTime</td><td><function>op:dateTime-less-than</function><code>(A, B)</code></td></tr>

<tr><td>A lt B</td><td>xs:yearMonthDuration</td><td>xs:yearMonthDuration</td><td><function>op:yearMonthDuration-less-than</function><code>(A, B)</code></td></tr>
<tr><td>A lt B</td><td>xs:dayTimeDuration</td><td>xs:dayTimeDuration</td><td><function>op:dayTimeDuration-less-than</function><code>(A, B)</code></td></tr>
<tr><td>A lt B</td><td>(xs:hexBinary | xs:base64Binary)</td><td>(xs:hexBinary | xs:base64Binary)</td><td><function>op:binary-less-than</function><code>(A, B)</code></td></tr>




</tbody>
</table>


            <p>The definitions of the operator functions are found in <bibref
                  ref="xpath-functions-40"/>.</p>

 
            <note>
               <p>Comparison of strings is defined
               by reference to the specification of the <function>fn:compare</function>
                  function with two arguments; this implies that the comparison is performed
                  using the <termref def="dt-def-collation"/> from the
                  <termref def="dt-static-context"/>.</p>
            </note>-->
               <p>Here are some examples of value comparisons:</p>
               <ulist>
                  <item>
                     <p>The following comparison atomizes the node(s) that are returned 
                     by the expression <code nobreak="false">$book/author</code>. The comparison is true 
                     only if the result of atomization is the value "Kennedy" as an 
                     instance of <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>. 
                     If the result of atomization is the empty sequence, the result of 
                     the comparison is the empty sequence. If the result of atomization 
                     is a sequence containing more than one value, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                     <eg role="parse-test" xml:space="preserve">$book1/author eq "Kennedy"</eg>
                  </item>
                  <item>
                     <p>The following comparison is <code nobreak="false">true</code> because atomization 
                     converts an array to its member sequence:</p>
                     <eg role="parse-test" xml:space="preserve">[ "Kennedy" ] eq "Kennedy"</eg>
                  </item>
                  <item>
                     <p>The following <termref def="dt-path-expression">path expression</termref> contains a predicate that selects 
                     products whose weight is greater than 100. For any product that 
                     does not have a <code nobreak="false">weight</code> subelement, the value of the 
                     predicate is the empty sequence, and the product is not selected. 
                     This example assumes that <code nobreak="false">weight</code> is a validated element 
                     with a numeric type.</p>
                     <eg role="parse-test" xml:space="preserve">//product[weight gt 100]</eg>
                  </item>
                  <item role="xquery">
                     <p>The following comparisons are true because, in each case, the two constructed 
                     nodes have the same value after atomization, even though they have different 
                     identities and/or names:</p>
                     <eg role="parse-test" xml:space="preserve">&lt;a&gt;5&lt;/a&gt; eq &lt;a&gt;5&lt;/a&gt;</eg>
                     <eg role="parse-test" xml:space="preserve">&lt;a&gt;5&lt;/a&gt; eq &lt;b&gt;5&lt;/b&gt;</eg>
                  </item>
                  <item>
                     <p>The following comparison is true if <code nobreak="false">my:hatsize</code> and 
                     <code nobreak="false">my:shoesize</code> are both user-defined types that are derived 
                     by restriction from a primitive <termref def="dt-numeric">numeric</termref> type:</p>
                     <eg role="parse-test" xml:space="preserve">my:hatsize(5) eq my:shoesize(5)</eg>
                  </item>
                  <item>
                     <p>The following comparison is true. The <code nobreak="false">eq</code> operator compares 
                     two QNames by performing codepoint-comparisons of their namespace URIs 
                     and their local names, ignoring their namespace prefixes.</p>
                     <eg role="parse-test" xml:space="preserve">QName("http://example.com/ns1", "this:color") eq
QName("http://example.com/ns1", "that:color")</eg>
                  </item>
                  <item>
                     <p>The following comparison is false. The <code nobreak="false">xs:double</code> value
                  <code nobreak="false">1.1e0</code> is converted to type <code nobreak="false">xs:decimal</code>, giving
                  the result <code nobreak="false">1.100000000000000088817841970012523233890533447265625</code>, 
                  which is not equal to the <code nobreak="false">xs:decimal</code> value <code nobreak="false">1.1</code>.</p>
                     <eg role="parse-test" xml:space="preserve">1.1 eq 1.1e0</eg>
                     <note>
                        <p>This is incompatible with previous versions, which converted
                  both operands to <code nobreak="false">xs:double</code> before comparing them. This change
                  has been made because there are contexts (such as sorting and grouping) where it
                  is important that comparison results should be transitive, and this was
                  not previously the case.</p>
                     </note>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-general-comparisons">
               <head>General Comparisons</head>
               <changes>
                  <change issue="986" PR="2218" date="2025-09-29">The rules for comparing untyped atomic items with numeric values have changed. 
                  Rather than converting an untyped atomic item unconditionally to <code nobreak="false">xs:double</code>,
                  it is now converted to the type of the numeric operand. This is designed to ensure that
                  comparisons such as <code nobreak="false">&lt;a&gt;1.1&lt;/a&gt; = 1.1</code> succeed, given that the values
                  will now be compared as decimals rather than as doubles.</change>
               </changes>
               <p>The general comparison operators are <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>. General comparisons are existentially quantified comparisons that may be applied to operand sequences of any length. The result of a general comparison that does not raise an error is
always <code nobreak="false">true</code> or <code nobreak="false">false</code>.</p>
               <p>
                  <phrase role="xquery">A</phrase> general comparison is evaluated by applying the following rules, in order:</p>
               <olist>
                  <item>
                     <p>
                        <termref def="dt-atomization">Atomization</termref> is applied to each operand. After atomization, each 
                     operand is a sequence of atomic items.</p>
                  </item>
                  <item>
                     <p>The result of the comparison is <code nobreak="false">true</code> if and only if there is a pair of
atomic items, one in the first operand sequence and the other in the second operand sequence, that have the required
<term>magnitude relationship</term>. Otherwise the result of the  comparison is
<code nobreak="false">false</code> or an error. The <term>magnitude relationship</term> between two atomic items is determined by
applying the following rules. If a <code nobreak="false">cast</code> operation called for by these rules is not successful, a <termref def="dt-dynamic-error">dynamic error</termref>  is raised. <xerrorref spec="FO40" class="RG" code="0001"/>
                     </p>
                     <note role="xquery">
                        <p>The purpose of these rules is to preserve a level of 
                        compatibility with XPath 1.0, in which (for example) <code role="parse-test" nobreak="false">x &lt; 17</code> is a numeric comparison if <code nobreak="false">x</code> is an untyped value. 
                        Users should be aware that the value comparison operators have different rules 
                        for casting of <code nobreak="false">xs:untypedAtomic</code> operands.</p>
                     </note>
                     <olist>
                        <item>
                           <p>If both atomic items are instances of <code nobreak="false">xs:untypedAtomic</code>,
                then the values are cast to the type <code nobreak="false">xs:string</code>.
             </p>
                        </item>
                        <item>
                           <p>If exactly one of the atomic items is an instance of
                <code nobreak="false">xs:untypedAtomic</code>, it is cast to a type depending on
                the other value’s dynamic type <var>T</var> according to the following rules,
                in which <var>V</var> denotes the value to be cast:
             </p>
                           <olist>
                              <item>
                                 <p>If <var>T</var> is a numeric type or is derived from a numeric type,
                      then <var>V</var> is cast first to the primitive base type of <var>T</var>
                                 (one of <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:double</code>,
                                 or <code nobreak="false">xs:float</code>); or if that fails, to <code nobreak="false">xs:double</code>.</p>
                                 <note>
                                    <p>Casting to <code nobreak="false">xs:decimal</code> might fail if <var>V</var>
                              uses exponential notation or is positive or negative infinity. Casting to
                              <code nobreak="false">xs:float</code> might fail because of numeric overflow.</p>
                                 </note>
                              </item>
                              <!--<item>
                              <p>If <var>T</var> is <code>xs:dayTimeDuration</code> or is derived from
                      <code>xs:dayTimeDuration</code>,
                      then <var>V</var> is cast to <code>xs:dayTimeDuration</code>.</p>
                           </item>
                           <item>
                              <p>If <var>T</var> is <code>xs:yearMonthDuration</code> or is derived from
                      <code>xs:yearMonthDuration</code>,
                      then <var>V</var> is cast to <code>xs:yearMonthDuration</code>.</p>
                           </item>-->
                              <item>
                                 <p>In all other cases, <var>V</var> is cast to the primitive base type of <var>T</var>.</p>
                              </item>
                           </olist>
                           <!--<note>
                           <p>
                The special treatment of the duration types is required to avoid
                errors that may arise when comparing the primitive type
                <code>xs:duration</code> with any duration type.
             </p>
                        </note>-->
                        </item>
                        <item>
                           <p>After performing the conversions described above, the atomic items are
compared using one of the 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>, or
<code nobreak="false">ge</code>, depending on whether the general comparison operator was <code nobreak="false">=</code>, <code nobreak="false">!=</code>, <code nobreak="false">&lt;</code>, <code nobreak="false">&lt;=</code>,
<code nobreak="false">&gt;</code>, or <code nobreak="false">&gt;=</code>. The values have the required <term>magnitude relationship</term> if and only if the result
of this value comparison is <code nobreak="false">true</code>.</p>
                        </item>
                     </olist>
                  </item>
               </olist>
               <p>When evaluating a general comparison in which either operand is a sequence of items, 
               an implementation may return <code nobreak="false">true</code> as soon as it finds an item in the 
               first operand and an item in the second operand that have the required 
               <term>magnitude relationship</term>. Similarly, a general comparison may raise a <termref def="dt-dynamic-error">dynamic error</termref> as soon as it encounters an error in evaluating 
               either operand, or in comparing a pair of items from the two operands. 
               As a result of these rules, the result of a general comparison is not 
               deterministic in the presence of errors.</p>
               <p>Here are some examples of general comparisons:</p>
               <ulist>
                  <item>
                     <p>The following comparison is true if the <termref def="dt-typed-value">typed value</termref> of any
<code nobreak="false">author</code> child element of <code nobreak="false">$book1</code> is "Kennedy" as an instance of <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>:</p>
                     <eg role="parse-test" xml:space="preserve">$book1/author = "Kennedy"</eg>
                  </item>
                  <item>
                     <p>The following comparison is true if the <termref def="dt-typed-value">typed value</termref> of any
<code nobreak="false">price</code> child element of <code nobreak="false">$book1</code> is (say) <code nobreak="false">"8.95"</code> as an instance of 
                     <code nobreak="false">xs:untypedAtomic</code>:</p>
                     <eg role="parse-test" xml:space="preserve">$book1/price &gt; 8.50</eg>
                     <p>Because the operand <code nobreak="false">8.50</code> is expressed as an <code nobreak="false">xs:decimal</code>,
                  the <code nobreak="false">xs:untypedAtomic</code> value of the element node is converted
                  to type <code nobreak="false">xs:decimal</code>, and the two <code nobreak="false">xs:decimal</code>
                  values are compared.</p>
                  </item>
                  <item>
                     <p>Given the input <code nobreak="false">&lt;item price="10.30"/&gt;</code>, the expression 
                  <code nobreak="false">@discount != "25%"</code> returns false, because there is no 
                  <code nobreak="false">discount</code> attribute that meets the specified criteria. By contrast,
                  the expression <code nobreak="false">not(@discount = "25%")</code> returns true.</p>
                  </item>
                  <item>
                     <p>The following comparison is <code nobreak="false">true</code> because atomization converts an array to its member sequence:</p>
                     <eg role="parse-test" xml:space="preserve">[ "Obama", "Nixon", "Kennedy" ] = "Kennedy"</eg>
                  </item>
                  <item>
                     <p>The following example contains three general comparisons. The value of the first two 
                     comparisons is <code nobreak="false">true</code>, and the value of the third comparison is 
                     <code nobreak="false">false</code>. This example illustrates the fact that general comparisons are not transitive.</p>
                     <eg xml:space="preserve">(1, 2) = (2, 3)
(2, 3) = (3, 4)
(1, 2) = (3, 4)</eg>
                  </item>
                  <item>
                     <p>The following example contains two general comparisons, both of which are <code nobreak="false">true</code>. 
                     This example illustrates the fact that the <code nobreak="false">=</code> and <code nobreak="false">!=</code> operators 
                     are not inverses of each other.</p>
                     <eg xml:space="preserve">(1, 2) = (2, 3)
(1, 2) != (2, 3)</eg>
                  </item>
                  <item>
                     <p>Suppose that <code nobreak="false">$a</code>, <code nobreak="false">$b</code>, and <code nobreak="false">$c</code> are bound to 
                     element nodes with type annotation <code nobreak="false">xs:untypedAtomic</code>, with <termref def="dt-string-value">string values</termref>
                        <code nobreak="false">"1"</code>, <code nobreak="false">"2"</code>, and <code nobreak="false">"2.0"</code> respectively. 
                     Then <code role="parse-test" nobreak="false">($a, $b) = ($c, 3.0)</code> returns <code nobreak="false">false</code>, because 
                     <code nobreak="false">$b</code> and <code nobreak="false">$c</code> are compared as strings. However, <code role="parse-test" nobreak="false">($a, $b) = ($c, 2.0)</code> returns <code nobreak="false">true</code>, 
                     because <code nobreak="false">$b</code> and <code nobreak="false">2.0</code> are compared as <code nobreak="false">xs:decimal</code> numbers.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-node-comparisons">
               <head>GNode Comparisons</head>
               <changes>
                  <change date="2025-07-28" PR="2130">
                  Operator <code nobreak="false">is-not</code> is introduced, as a complement to the operator <code nobreak="false">is</code>.
               </change>
                  <change date="2025-07-28" PR="2130">
                  Operators <code nobreak="false">precedes</code> and <code nobreak="false">follows</code> are introduced as synonyms
                  for operators <code nobreak="false">&lt;&lt;</code> and <code nobreak="false">&gt;&gt;</code>.
               </change>
                  <change date="2025-08-22" PR="2176">
                  Operators <code nobreak="false">precedes-or-is</code> and <code nobreak="false">follows-or-is</code> are introduced as synonyms
                  for the union of operators <code nobreak="false">&lt;&lt;</code> and <code nobreak="false">is</code> and for the union of 
                  operators <code nobreak="false">&gt;&gt;</code> and <code nobreak="false">is</code>, respectively.
               </change>
               </changes>
               <p>GNode comparisons are used to compare two <termref def="dt-GNode">GNodes</termref>

               (that is, <termref def="dt-XNode">XNodes</termref> or
               <xtermref spec="DM40" ref="dt-JNode">JNodes</xtermref>), by their identity or by their <termref def="dt-document-order">document order</termref>. The result of a GNode comparison is defined by the following rules:</p>
               <olist>
                  <item>
                     <p>The operands of a <termref def="dt-GNode"/> comparison are evaluated in <termref def="dt-implementation-dependent">implementation-dependent</termref> order.</p>
                  </item>
                  <item>
                     <p>If either operand is the empty sequence, the result of the
    comparison is the empty sequence, and the implementation need not
    evaluate the other operand or apply the operator. However, an
    implementation may choose to evaluate the other operand in order to
    determine whether it raises an error.</p>
                  </item>
                  <item>
                     <p> Each operand must be either a single <termref def="dt-GNode"/> or the empty sequence; otherwise
a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                  </item>
                  <item>
                     <p>A comparison with the <code nobreak="false">is</code> operator is <code nobreak="false">true</code> if 
                     the values of two operands are the same GNode; otherwise it
is <code nobreak="false">false</code>. See <bibref ref="xpath-datamodel-40"/> for  the definition of GNode identity.</p>
                  </item>
                  <item>
                     <p>A comparison with the <code nobreak="false">is-not</code> operator is <code nobreak="false">false</code> if 
                     the values of two operands are the same GNode; otherwise it
is <code nobreak="false">true</code>. See <bibref ref="xpath-datamodel-40"/> for  the definition of GNode identity.</p>
                  </item>
                  <item>
                     <p>A comparison with the <code nobreak="false">&lt;&lt;</code> or <code nobreak="false">precedes</code> operator returns <code nobreak="false">true</code> 
                     if the left operand <termref def="dt-GNode"/> precedes the right operand GNode in

<termref def="dt-document-order">document order</termref>; otherwise it returns <code nobreak="false">false</code>.</p>
                  </item>
                  <item>
                     <p>A comparison with the <code nobreak="false">&gt;&gt;</code> or <code nobreak="false">follows</code> operator returns 
                     <code nobreak="false">true</code> if the left operand GNode follows the right operand GNode in
<termref def="dt-document-order">document order</termref>; otherwise it returns <code nobreak="false">false</code>.</p>
                  </item>
                  <item>
                     <p>A comparison with the <code nobreak="false">precedes-or-is</code> operator returns <code nobreak="false">true</code> 
                     if the left operand <termref def="dt-GNode"/> precedes the right operand GNode in
                     
                     <termref def="dt-document-order">document order</termref> or if the values of two operands 
                     are the same GNode; otherwise it returns <code nobreak="false">false</code>.</p>
                  </item>
                  <item>
                     <p>A comparison with the <code nobreak="false">follows-or-is</code> operator returns <code nobreak="false">true</code> 
                     if the left operand <termref def="dt-GNode"/> follows the right operand GNode in
                     
                     <termref def="dt-document-order">document order</termref> or if the values of two operands 
                     are the same GNode; otherwise it returns <code nobreak="false">false</code>.</p>
                  </item>
               </olist>
               <p>Here are some examples of GNode comparisons:</p>
               <ulist>
                  <item>
                     <p>The following comparison is true only if the left and right sides each
evaluate to exactly the same single node:</p>
                     <eg role="parse-test" xml:space="preserve">/books/book[isbn = "1558604820"] is /books/book[call = "QA76.9 C3845"]</eg>
                  </item>
                  <item role="xquery">
                     <p>The following comparison is false because each constructed node has its own identity:</p>
                     <eg role="parse-test" xml:space="preserve">&lt;a&gt;5&lt;/a&gt; is &lt;a&gt;5&lt;/a&gt;</eg>
                  </item>
                  <item>
                     <p>The following comparison is true only if the node identified by the left
side occurs before the node identified by the right side in document order:</p>
                     <eg role="parse-test" xml:space="preserve">/transactions/purchase[parcel = "28-451"] &lt;&lt; /transactions/sale[parcel = "33-870"]</eg>
                  </item>
                  <item>
                     <p>The following comparison is true only if the first integer 
                     among the members of an array precedes the first string. This expression
                     compares two JNodes:</p>
                     <eg role="parse-test" xml:space="preserve">let $A := ["Q", 3, "E", "R", "T", 5, "Y"]
return $A ? child::type(xs:integer)[1] precedes $A ? child::type(xs:string)[1]</eg>
                  </item>
               </ulist>
            </div3>
         </div2>
         <div2 id="id-logical-expressions">
            <head>Logical Expressions</head>
            <changes>
               <change issue="71 2132" PR="230" date="2022-11-15">
                  The rules for “errors and optimization” have been tightened up to disallow
                  many cases of optimizations that alter error behavior. In particular
                  there are restrictions on reordering the operands of <code nobreak="false">and</code> and <code nobreak="false">or</code>,
                  and of predicates in filter expressions, in a way that might allow the processor to raise dynamic
                  errors that the author intended to prevent.
               </change>
            </changes>
            <p>
               <termdef id="dt-logical-expression" term="logical expression">
            A <term>logical expression</term> is either an <termref def="dt-and-expression"/>
            or an <termref def="dt-or-expression"/>. If a logical expression does not raise an error, 
            its value is always one of the boolean values <code nobreak="false">true</code> or <code nobreak="false">false</code>.</termdef>
            </p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-OrExpr">
                  <lhs>OrExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AndExpr">AndExpr<!--$idref_lang_part = xquery40- --></nt>  ("or"  <nt def="prod-xquery40-AndExpr">AndExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-OrExpr-AndExpr">
                  <lhs>AndExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ComparisonExpr">ComparisonExpr<!--$idref_lang_part = xquery40- --></nt>  ("and"  <nt def="prod-xquery40-ComparisonExpr">ComparisonExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-OrExpr-ComparisonExpr">
                  <lhs>ComparisonExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-OtherwiseExpr">OtherwiseExpr<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-ValueComp">ValueComp<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-GeneralComp">GeneralComp<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NodeComp">NodeComp<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-OtherwiseExpr">OtherwiseExpr<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-and-expression" term="and expression">An <term>and expression</term>
         is a <termref def="dt-non-trivial"/> instance of the production <nt def="prod-xquery40-AndExpr">AndExpr<!--$spec = xquery40--></nt>.</termdef>
            </p>
            <p>
               <termdef id="dt-or-expression" term="or expression">An <term>or expression</term>
         is a <termref def="dt-non-trivial"/> instance of the production <nt def="doc-xquery40-OrExpr">OrExpr<!--$spec = xquery40--></nt>.</termdef>
            </p>
            <p>In the absence of errors, an <termref def="dt-and-expression"/> returns <code nobreak="false">true</code>
            when both of its operands have an <termref def="dt-ebv"/> of <code nobreak="false">true</code>, while an
            <termref def="dt-or-expression"/> returns <code nobreak="false">true</code> when either or both of its operands have
            an <termref def="dt-ebv"/> of <code nobreak="false">true</code>.</p>
            <p>The rules for error handling follow the principles defined in <specref ref="id-guarded-expressions"/>.
         Specifically, an <termref def="dt-and-expression"/> returns false if the first operand has an 
         <termref def="dt-ebv"/> of <code nobreak="false">false</code>, whether or not evaluation of the second
         operand raises an error; while an <termref def="dt-or-expression"/> returns true if the first operand has an 
         <termref def="dt-ebv"/> of <code nobreak="false">true</code>, whether or not evaluation of the second
         operand raises an error.</p>
            <note>
               <p>This rule is consistent with the so-called “short-circuit” evaluation of
         logical operators defined in some procedural programming languages. However, unlike many
         such languages, the rule is concerned only with error behavior, and not with side-effects.
         A processor may evaluate the operands of a logical expression in any order, or in parallel,
         provided that the error semantics are respected. For example, an optimizer may choose to
         evaluate the second operand before evaluating the first, provided that any error in doing so
         is masked when the result can be determined from the value of the first operand.</p>
            </note>
            <p>The value of an <termref def="dt-and-expression"/> is determined by the effective
          boolean values (EBVs) of its operands, as shown in the following table:</p>
            <table role="medium" width="80%" border="1">
               <tbody>
                  <tr>
                     <th rowspan="1" colspan="1">AND:</th>
                     <th rowspan="1" colspan="1">EBV<sub>2</sub> =
<code nobreak="false">true</code>
                     </th>
                     <th rowspan="1" colspan="1">EBV<sub>2</sub> = <code nobreak="false">false</code>
                     </th>
                     <th rowspan="1" colspan="1">error in EBV<sub>2</sub>
                     </th>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">EBV<sub>1</sub> =
<code nobreak="false">true</code>
                     </th>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">true</code>
                     </td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">false</code>
                     </td>
                     <td rowspan="1" colspan="1">error</td>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">EBV<sub>1</sub>
= <code nobreak="false">false</code>
                     </th>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">false</code>
                     </td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">false</code>
                     </td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">false</code>
                     </td>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">error in EBV<sub>1</sub>
                     </th>
                     <td rowspan="1" colspan="1">error</td>
                     <td rowspan="1" colspan="1">error</td>
                     <td rowspan="1" colspan="1">error</td>
                  </tr>
               </tbody>
            </table>
            <p>The value of an
<termref def="dt-or-expression"/> is determined by the effective boolean values (EBVs) of
its operands, as shown in
the following table:</p>
            <table role="medium" width="80%" border="1">
               <tbody>
                  <tr>
                     <th rowspan="1" colspan="1">OR:</th>
                     <th rowspan="1" colspan="1">EBV<sub>2</sub> =
<code nobreak="false">true</code>
                     </th>
                     <th rowspan="1" colspan="1">EBV<sub>2</sub> = <code nobreak="false">false</code>
                     </th>
                     <th rowspan="1" colspan="1">error in
EBV<sub>2</sub>
                     </th>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">EBV<sub>1</sub> =
<code nobreak="false">true</code>
                     </th>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">true</code>
                     </td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">true</code>
                     </td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">true</code>
                     </td>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">EBV<sub>1</sub> =
<code nobreak="false">false</code>
                     </th>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">true</code>
                     </td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">false</code>
                     </td>
                     <td rowspan="1" colspan="1">error</td>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">error
in EBV<sub>1</sub>
                     </th>
                     <td rowspan="1" colspan="1">error</td>
                     <td rowspan="1" colspan="1">error</td>
                     <td rowspan="1" colspan="1">error</td>
                  </tr>
               </tbody>
            </table>
            <note>
               <p>XPath 1.0 defined the order of evaluation for 
               <termref def="dt-and-expression">and-expressions</termref> and 
               <termref def="dt-or-expression">or-expressions</termref>, thus ensuring
               “short-circuit” semantics. XPath 2.0 and XQuery 1.0 changed the rules
               to allow operands to be evaluated in either order, in the interests
               of optimization, while retaining “short-circuit” semantics when
               running XPath in 1.0 compatibility mode. The same rules were retained in
               the 3.0 and 3.1 versions of the specifications.</p>
               <p>The disadvantage
               of that formulation was that it was not possible to use the first operand
               of a logical expression to guard against dynamic errors in the second;
               for example the expression <code nobreak="false">$n instance of node() and exists($n/*)</code>
               might legitimately fail in the case where <code nobreak="false">$n</code> is not a node.</p>
               <p>The 4.0 specification therefore guarantees that this expression will not fail;
               but it does so without mandating an order of evaluation for the operands. Instead
               it mandates only that any error in evaluating the second operand (<code nobreak="false">exists($n/*)</code>)
               is masked if the first operand (<code nobreak="false">$n instance of node()</code>) is false.
            </p>
            </note>
            <p>Here are some examples of logical expressions:</p>
            <ulist>
               <item>
                  <p>The following expressions return
<code nobreak="false">true</code>:</p>
                  <eg role="parse-test" xml:space="preserve">1 eq 1 and 2 eq 2</eg>
                  <eg role="parse-test" xml:space="preserve">1 eq 1 or 2 eq 3</eg>
               </item>
               <item>
                  <p>The following returns <code nobreak="false">false</code>: it is not allowed to
               raise an error.</p>
                  <eg role="parse-test" xml:space="preserve">1 eq 2 and 3 idiv 0 = 1</eg>
               </item>
               <item>
                  <p>The following expression returns <code nobreak="false">true</code>: it is not allowed to
               raise an error.</p>
                  <eg role="parse-test" xml:space="preserve">1 eq 1 or 3 idiv 0 = 1</eg>
               </item>
               <item>
                  <p>The
following expression must raise a <termref def="dt-dynamic-error">dynamic error</termref>:</p>
                  <eg role="parse-test" xml:space="preserve">1 eq 1 and 3 idiv 0 = 1</eg>
               </item>
            </ulist>
            <p>In addition to and- and or-expressions, XQuery 4.0 provides a
function named <function>fn:not</function> that takes a general sequence as
parameter and returns a boolean value.  The <function>fn:not</function> function
is defined in <bibref ref="xpath-functions-40"/>. The
<function>fn:not</function> function reduces its parameter to an <termref def="dt-ebv">effective boolean value</termref>. It then returns
<code nobreak="false">true</code> if the effective boolean value of its parameter is
<code nobreak="false">false</code>, and <code nobreak="false">false</code> if the effective boolean
value of its parameter is <code nobreak="false">true</code>. If an error is
encountered in finding the effective boolean value of its operand,
<function>fn:not</function> raises the same error.</p>
         </div2>
         <div2 id="id-constructors">
            <head>Node Constructors</head>
            <changes>
               <change issue="2427" PR="2446" date="2026-02-07">
               Computed node constructors are now available in XPath as well as XQuery.
            </change>
            </changes>
            <p>XQuery 4.0 provides node constructors that can create XML nodes within a query.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-NodeConstructor">
                  <lhs>NodeConstructor</lhs>
                  <rhs>
                     <nt def="prod-xquery40-DirectConstructor">DirectConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ComputedConstructor">ComputedConstructor<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirectConstructor">
                  <lhs>DirectConstructor</lhs>
                  <rhs>
                     <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-DirCommentConstructor">DirCommentConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-DirPIConstructor">DirPIConstructor<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirElemConstructor">
                  <lhs>DirElemConstructor</lhs>
                  <rhs>"&lt;"  <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-DirAttributeList">DirAttributeList<!--$idref_lang_part = xquery40- --></nt>  ("/&gt;"  |  ("&gt;"  <nt def="prod-xquery40-DirElemContent">DirElemContent<!--$idref_lang_part = xquery40- --></nt>*  "&lt;/"  <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>?  "&gt;"))</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirAttributeList">
                  <lhs>DirAttributeList</lhs>
                  <rhs>(<nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>?  "="  <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-DirAttributeValue">DirAttributeValue<!--$idref_lang_part = xquery40- --></nt>)?)*</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirAttributeValue">
                  <lhs>DirAttributeValue</lhs>
                  <rhs>('"'  (<nt def="prod-xquery40-EscapeQuot">EscapeQuot<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotAttrValueContent">QuotAttrValueContent<!--$idref_lang_part = xquery40- --></nt>)*  '"')<br/>|  ("'"  (<nt def="prod-xquery40-EscapeApos">EscapeApos<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-AposAttrValueContent">AposAttrValueContent<!--$idref_lang_part = xquery40- --></nt>)*  "'")</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-QuotAttrValueContent">
                  <lhs>QuotAttrValueContent</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QuotAttrContentChar">QuotAttrContentChar<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CommonContent">CommonContent<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-AposAttrValueContent">
                  <lhs>AposAttrValueContent</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposAttrContentChar">AposAttrContentChar<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CommonContent">CommonContent<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirElemContent">
                  <lhs>DirElemContent</lhs>
                  <rhs>
                     <nt def="prod-xquery40-DirectConstructor">DirectConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CDataSection">CDataSection<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CommonContent">CommonContent<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-ElementContentChar">ElementContentChar<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirCommentConstructor">
                  <lhs>DirCommentConstructor</lhs>
                  <rhs>"&lt;!--"  <nt def="prod-xquery40-DirCommentContents">DirCommentContents<!--$idref_lang_part = xquery40- --></nt>  "--&gt;"</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirPIConstructor">
                  <lhs>DirPIConstructor</lhs>
                  <rhs>"&lt;?"  <nt def="prod-xquery40-PITarget">PITarget<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-DirPIContents">DirPIContents<!--$idref_lang_part = xquery40- --></nt>)?  "?&gt;"</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-CDataSection">
                  <lhs>CDataSection</lhs>
                  <rhs>"&lt;![CDATA["  <nt def="prod-xquery40-CDataSectionContents">CDataSectionContents<!--$idref_lang_part = xquery40- --></nt>  "]]&gt;"</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-CDataSectionContents">
                  <lhs>CDataSectionContents</lhs>
                  <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* ']]&gt;' Char*))</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-Char">
                  <lhs>Char</lhs>
                  <rhs>
                     <xnt ref="NT-Char" spec="XML">[http://www.w3.org/TR/REC-xml#NT-Char]</xnt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-CommonContent">
                  <lhs>CommonContent</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  "{{"  |  "}}"  |  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-EnclosedExpr">
                  <lhs>EnclosedExpr</lhs>
                  <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-ElementContentChar">
                  <lhs>ElementContentChar</lhs>
                  <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - [{}&lt;&amp;])</rhs>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-DirCommentContents">
                  <lhs>DirCommentContents</lhs>
                  <rhs>((<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - '-')  |  ("-"  (<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - '-')))*</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NodeConstructor-ComputedConstructor">
                  <lhs>ComputedConstructor</lhs>
                  <rhs>
                     <nt def="prod-xquery40-CompDocConstructor">CompDocConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CompElemConstructor">CompElemConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CompAttrConstructor">CompAttrConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CompNamespaceConstructor">CompNamespaceConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CompTextConstructor">CompTextConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CompCommentConstructor">CompCommentConstructor<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-CompPIConstructor">CompPIConstructor<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p>Constructors are provided for element, attribute, document, text, comment, 
            processing instruction, and namespace nodes. 
            <phrase role="xquery">Two kinds of constructors are provided: <term>direct constructors</term>, 
            which use an XML-like notation that can incorporate enclosed expressions, 
            and <term>computed constructors</term>, which use a notation based on enclosed expressions.</phrase>
            </p>
            <p>The rest of this section defines the semantics of various kinds of 
            constructor expressions.</p>
            <div3 id="id-element-constructor" role="xquery">
               <head>Direct Element Constructors</head>
               <p>An <term>element constructor</term> creates an element node. <termdef term="direct element constructor" id="dt-direct-elem-const">A <term>direct element constructor</term> is a form of element constructor in which the name 
               of the constructed element is a constant.</termdef> Direct element constructors are based on 
               standard XML notation. For example, the following expression is a direct element constructor
               that creates a <code nobreak="false">book</code> element containing an attribute and some nested elements:</p>
               <eg role="parse-test" xml:space="preserve">&lt;book isbn="isbn-0060229357"&gt;
  &lt;title&gt;Harold and the Purple Crayon&lt;/title&gt;
  &lt;author&gt;
    &lt;first&gt;Crockett&lt;/first&gt;
    &lt;last&gt;Johnson&lt;/last&gt;
  &lt;/author&gt;
&lt;/book&gt;</eg>
               <p>The element name, written as a lexical QName, is expanded using the
            <termref def="dt-constructed-element-namespace-rule"/>.</p>
               <!--<p>If the element name in a direct element constructor has a namespace prefix, the namespace prefix
               is resolved to a namespace URI using the <termref def="dt-static-namespaces"/>. 
               If the element name has no namespace prefix, <phrase diff="chg" at="2023-10-16">the 
                  <termref def="dt-namespace-binding"/> for the zero-length prefix in the <termref def="dt-static-namespaces"/>
               is used; if there is no such binding, the element name will be in no namespace</phrase>.</p>-->
               <note>
                  <p>The statically known namespaces 
               may be affected by <termref def="dt-namespace-decl-attr">namespace declaration attributes</termref> 
               found inside the element constructor.</p>
               </note>
               <p>The namespace prefix of the element name is retained after 
               expansion of the <termref def="dt-qname">lexical QName</termref>, as described in 
               <bibref ref="xpath-datamodel-40"/>. The resulting <termref def="dt-expanded-qname">expanded QName</termref> 
               becomes the <code nobreak="false">node-name</code> property of the constructed element node.</p>
               <p>The name used in the end tag must exactly match the name
used in the corresponding start tag, including its prefix or absence of a prefix  <errorref class="ST" code="0118"/>.</p>
               <p>In a direct element constructor, curly brackets 
               (<char>U+007B</char> and <char>U+007D</char>) delimit  <termref def="dt-enclosed-expression">enclosed expressions</termref>, distinguishing them from literal text. Enclosed expressions
are evaluated and replaced by their value, as illustrated by the following
example:</p>
               <eg role="parse-test" xml:space="preserve">&lt;example&gt;
  &lt;p&gt; Here is a query. &lt;/p&gt;
  &lt;eg&gt; $b/title &lt;/eg&gt;
  &lt;p&gt; Here is the result of the query. &lt;/p&gt;
  &lt;eg&gt;{ $b/title }&lt;/eg&gt;
&lt;/example&gt;</eg>
               <p>The above query might generate the following result (whitespace has been added for readability to this result and other result examples in this document):</p>
               <eg role="parse-test" xml:space="preserve">
&lt;example&gt;
  &lt;p&gt; Here is a query. &lt;/p&gt;
  &lt;eg&gt; $b/title &lt;/eg&gt;
  &lt;p&gt; Here is the result of the query. &lt;/p&gt;
  &lt;eg&gt;&lt;title&gt;Harold and the Purple Crayon&lt;/title&gt;&lt;/eg&gt;
&lt;/example&gt;</eg>
               <p>Since XQuery uses <char>U+007B</char> and <char>U+007D</char> to delimit enclosed expressions, some
convention is needed to denote a curly bracket used as an ordinary character. For
this purpose, a pair of identical curly bracket characters within the content of an element or attribute are interpreted by XQuery  as a single curly bracket
character (that is, the pair <code nobreak="false">"{{"</code> represents the
  character <char>U+007B</char> and the pair <code nobreak="false">"}}"</code> represents
  the character <char>U+007D</char>.) Alternatively, the <termref def="dt-character-reference">character references</termref>
                  <code nobreak="false">&amp;#x7b;</code> and <code nobreak="false">&amp;#x7d;</code> can be used to denote curly bracket characters.  
               A single <char>U+007B</char> is interpreted as the beginning delimiter for an
  enclosed expression. A single <char>U+007D</char>
  without a matching left curly bracket is treated as a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0003"/>.</p>
               <p>Within an enclosed expression, the handling of expressions that start with <char>U+007B</char> or that
            end with <char>U+007D</char> is the same as for <specref ref="id-string-templates"/>.</p>
               <p>The result of an element constructor is a new element node, with its own node identity. All the attribute and descendant nodes of the new element node are also new nodes with their own identities, even if they are copies of existing nodes.</p>
               <div4 id="id-attributes">
                  <head>Attributes</head>
                  <p>The start tag of a direct element constructor may contain one or more attributes. As in XML, each attribute is specified by a name and a value. In a direct element constructor, the name of each attribute is specified by a constant <termref def="dt-qname">lexical QName</termref>, and the value of the attribute is specified by a string of characters enclosed in single or double quotes. As in the main content of the element constructor, an attribute value may contain  <termref def="dt-enclosed-expression">enclosed expressions</termref>, which are evaluated and replaced by their value during processing of the element constructor.</p>
                  <p>Each attribute in a direct element constructor creates a new attribute node, with its own node identity, whose parent is the constructed element node. However, note that <termref def="dt-namespace-decl-attr">namespace declaration attributes</termref> (see <specref ref="id-namespaces"/>) do not create attribute nodes.</p>
                  <p>The attribute name, written as a lexical QName, is expanded using the <termref def="dt-no-namespace-rule"/>.</p>
                  <!--<p>If an attribute name has a namespace prefix, the prefix is resolved to a namespace URI using the <termref
                     def="dt-static-namespaces"
                     >statically known namespaces</termref>. If the attribute name  has no namespace prefix, the attribute is in no namespace. -->
                  <note>
                     <p>
                  The <termref def="dt-static-namespaces"/> used in resolving an attribute name may be affected by <termref def="dt-namespace-decl-attr">namespace declaration attributes</termref> that are found inside the same element constructor.
               </p>
                  </note>
                  <p>
                  The namespace prefix of the attribute name is retained after expansion of the <termref def="dt-qname">lexical QName</termref>, as described in <bibref ref="xpath-datamodel-40"/>. The resulting <termref def="dt-expanded-qname">expanded QName</termref> becomes the <code nobreak="false">node-name</code> property of the constructed attribute node.</p>
                  <p>If the attributes in a direct element constructor do not have distinct <termref def="dt-expanded-qname">expanded
			        QNames</termref> as their respective <code nobreak="false">node-name</code> properties, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0040"/>.</p>
                  <p>Conceptually, an attribute (other than a namespace declaration attribute) in a 
                  direct element constructor is processed by the following steps:</p>
                  <olist>
                     <item>
                        <p>Each consecutive sequence of literal characters in the
	attribute content is processed as a string literal containing
	those characters, with the following exceptions:</p>
                        <olist>
                           <item>
                              <p>Each occurrence of two consecutive <code nobreak="false">{</code>
             characters is replaced by a single <code nobreak="false">{</code> character.
             </p>
                           </item>
                           <item>
                              <p>Each occurrence of two consecutive <code nobreak="false">}</code>
             characters is replaced by a single <code nobreak="false">}</code> character.
             </p>
                           </item>
                           <item>
                              <p>Each occurrence of <nt def="prod-xquery40-EscapeQuot">EscapeQuot<!--$spec = xquery40--></nt> is replaced by a single
             <code nobreak="false">"</code> character.  </p>
                           </item>
                           <item>
                              <p>Each occurrence of <nt def="prod-xquery40-EscapeApos">EscapeApos<!--$spec = xquery40--></nt> is replaced by a single
             <code nobreak="false">'</code> character.  </p>
                           </item>
                        </olist>
                        <p>Within an enclosed expression, the handling of expressions that start with <char>U+007B</char> or that
            end with <char>U+007D</char> is the same as for <specref ref="id-string-templates"/>.</p>
                        <p>Attribute value normalization is then applied to
          normalize whitespace and expand <termref def="dt-character-reference">character references</termref>
          and <termref def="dt-predefined-entity-reference">predefined
          entity references</termref>. 
	  The rules for attribute value
	  normalization are the rules from Section 3.3.3 of [XML 1.0]
	  or Section 3.3.3 of [XML 1.1] (it is implementation-defined
	  which version is used). The rules are applied as though the
	  type of the attribute were CDATA (leading and trailing
	  whitespace characters are not stripped.)
          </p>
                     </item>
                     <item>
                        <p>Each enclosed expression is converted to a string as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <termref def="dt-atomization">Atomization</termref> is applied to the value of the enclosed expression, converting it to a sequence of atomic items.</p>
                           </item>
                           <item>
                              <p>If the result of atomization is the empty sequence, the result is the zero-length string. Otherwise, each atomic item in the atomized sequence is cast into a string.</p>
                           </item>
                           <item>
                              <p>The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair.</p>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>Adjacent strings resulting from the above steps are concatenated with no intervening blanks. The resulting string becomes the <code nobreak="false">string-value</code> property of the attribute node. The attribute node is given a <termref def="dt-type-annotation">type annotation</termref> of <code nobreak="false">xs:untypedAtomic</code> (this type annotation may change if the parent element is validated). The <code nobreak="false">typed-value</code> property of the attribute node is the same as its <code nobreak="false">string-value</code>, as an instance of <code nobreak="false">xs:untypedAtomic</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">parent</code> property of the attribute node is set to the element node constructed by the direct element constructor that contains this attribute.</p>
                     </item>
                     <item>
                        <p>If the attribute name is <code nobreak="false">xml:id</code>, then <code nobreak="false">xml:id</code> processing is performed as defined in <bibref ref="XMLID"/>. This ensures that the attribute has the type <code nobreak="false">xs:ID</code> and that its value is properly normalized. If an error is encountered during <code nobreak="false">xml:id</code> processing, an implementation may raise a <termref def="dt-dynamic-error">dynamic error</termref>
                           <errorref class="DY" code="0091"/>.</p>
                     </item>
                     <item>
                        <p>If the attribute name is <code nobreak="false">xml:id</code>, the <code nobreak="false">is-id</code> property of the resulting attribute node is set to <code nobreak="false">true</code>; otherwise the <code nobreak="false">is-id</code> property is set to <code nobreak="false">false</code>. The <code nobreak="false">is-idrefs</code> property of the attribute node is unconditionally set to <code nobreak="false">false</code>.</p>
                     </item>
                  </olist>
                  <ulist>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;shoe size="7"/&gt;</eg>
                        <p>The string value of the <code nobreak="false">size</code> attribute is <code nobreak="false">"7"</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;shoe size="{ 7 }"/&gt;</eg>
                        <p>The string value of the <code nobreak="false">size</code> attribute is <code nobreak="false">"7"</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;shoe size="{ () }"/&gt;</eg>
                        <p>The string value of the <code nobreak="false">size</code> attribute is the zero-length string.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;chapter ref="[ { 1, 5 to 7, 9 } ]"/&gt;</eg>
                        <p>The string value of the <code nobreak="false">ref</code> attribute is <code nobreak="false">"[1 5 6 7 9]"</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;shoe size="As big as { $hat/@size }"/&gt;</eg>
                        <p>The string value of the <code nobreak="false">size</code> attribute is the
string <code nobreak="false">"As big as "</code>, concatenated with the string value of the
node denoted by the expression
  <code nobreak="false">$hat/@size</code>.</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-namespaces">
                  <head>Namespace Declaration Attributes</head>
                  <changes>
                     <change issue="65" PR="753" date="2023-10-31">
                     The <termref def="dt-default-namespace-elements-and-types"/> can now be declared to be fixed
                     for a query module, meaning it is unaffected by a namespace declaration appearing on a direct
                     element constructor.
                   </change>
                  </changes>
                  <p>The names of
  a constructed element and its attributes may be <termref def="dt-qname">lexical QNames</termref> that
  include <term>namespace prefixes</term>. Namespace prefixes can be
  bound to namespaces in the <termref def="dt-prolog">Prolog</termref> or by  <term>namespace
  declaration attributes</term>. It is a
  <termref def="dt-static-error">static error</termref> to use a
  namespace prefix that has not been bound to a namespace <errorref class="ST" code="0081"/>.</p>
                  <p>The syntax of <termref def="dt-namespace-decl-attr">namespace declaration attributes</termref> 
                mimics XML syntax. Examples are
               <code nobreak="false">xmlns:p="http://example.com/ns"</code> and <code nobreak="false">xmlns="http://example.com/ns"</code>.</p>
                  <p at="XQ.E13">
                     <termdef term="namespace declaration attribute" id="dt-namespace-decl-attr">A <term>namespace declaration
attribute</term> is used inside a direct element constructor. Its
purpose is to bind a namespace prefix <phrase diff="add" at="A">(including the zero-length prefix)</phrase> to a URI:
                     the binding is effective for
the constructed element node, including its attributes.</termdef>
                  </p>
                  <p>Syntactically, a namespace declaration attribute has the form of an
attribute with namespace prefix <code nobreak="false">xmlns</code>, or with name
<code nobreak="false">xmlns</code> and no namespace prefix. All the namespace
declaration attributes of a given element must have distinct names
<errorref class="ST" code="0071"/>.</p>
                  <p>Each namespace declaration
attribute is processed as follows:</p>
                  <olist>
                     <item at="XQ.E13">
                        <p>The value of the namespace declaration attribute (a <nt def="prod-xquery40-DirAttributeValue">DirAttributeValue<!--$spec = xquery40--></nt>) is processed as follows. If the <nt def="prod-xquery40-DirAttributeValue">DirAttributeValue<!--$spec = xquery40--></nt> contains an <nt def="doc-xquery40-EnclosedExpr">EnclosedExpr<!--$spec = xquery40--></nt>, a static error is raised <errorref class="ST" code="0022"/>. Otherwise, it is processed as described in rule 1 of <specref ref="id-attributes"/>. An implementation <rfc2119>may</rfc2119> raise a static error <errorref class="ST" code="0046"/> if the resulting value is of
                           nonzero length and is neither an absolute URI nor a
                           relative URI. The resulting value <var>U</var> is used as the namespace
                           URI in the following rules.
                           </p>
                     </item>
                     <item>
                        <p>If the attribute name is in the form <code nobreak="false">xmlns:<var>P</var>
                           </code>, then 
                        <var>P</var> is interpreted as a namespace prefix.</p>
                        <olist>
                           <item>
                              <p>If <var>U</var> is of nonzero length, then
                                the <termref def="dt-namespace-binding"/>
                                 <code nobreak="false">
                                    <var>P</var>=<var>U</var>
                                 </code>
                                is added both to the <termref def="dt-static-namespaces">statically known namespaces</termref>
                     of the constructor expression (overriding any existing binding of
                     the given prefix), and also to the
                     <termref def="dt-in-scope-namespaces">in-scope namespaces</termref>
                        of the constructed element.</p>
                           </item>
                           <item>
                              <p>If the namespace URI is a zero-length
                        string and the implementation supports <bibref ref="XMLNAMES11"/>,
                        any existing namespace binding for the given prefix is removed from the
                        <termref def="dt-in-scope-namespaces">in-scope namespaces</termref>
                        of the constructed element and from the
                        <termref def="dt-static-namespaces">statically known namespaces</termref>
                        of the constructor expression.</p>
                           </item>
                           <item>
                              <p>If the namespace URI is a zero-length
                        string and the implementation does not support <bibref ref="XMLNAMES11"/>,
                        a static error is raised <errorref code="0085" class="ST"/>. It is
                        <termref def="dt-implementation-defined">implementation-defined</termref>
                        whether an implementation supports <bibref ref="XMLNAMES"/> or
                        <bibref ref="XMLNAMES11"/>.</p>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>If the name of the namespace declaration attribute is 
                        in the form <code nobreak="false">xmlns</code> then:</p>
                        <olist>
                           <item>
                              <p>If <var>U</var> is a zero-length string, then:</p>
                              <olist>
                                 <item>
                                    <p>Any <termref def="dt-default-in-scope-namespace"/> is removed from the
                                 <termref def="dt-in-scope-namespaces"/> of the constructed element
                                 and from the <termref def="dt-static-namespaces">statically known namespaces</termref>
                                 of the constructor expression.</p>
                                 </item>
                                 <item>
                                    <p>Unless
                                 the query prolog contains a default namespace declaration or import schema declaration
                                 defining the <termref def="dt-default-namespace-elements-and-types"/> as being
                                 <code nobreak="false">fixed</code>, the <termref def="dt-default-namespace-elements-and-types"/> 
                                 in the static context of the element constructor 
                                 is set to <xtermref ref="dt-absent" spec="DM40"/>.</p>
                                 </item>
                              </olist>
                           </item>
                           <item>
                              <p>Otherwise (when <var>U</var> is not a zero-length string):
                           <olist>
                                    <item>
                                       <p>The namespace binding <code nobreak="false">""=<var>U</var>
                                          </code> (that is, a binding
                                    of the zero-length prefix to the namespace URI <var>U</var>)
                                    is added both to the <termref def="dt-in-scope-namespaces">in-scope namespaces</termref> of the constructed element 
                                 (overriding any existing binding of the zero-length prefix), 
                                 and to the <termref def="dt-static-namespaces">statically known namespaces</termref>
                                 of the constructor expression.</p>
                                    </item>
                                    <item>
                                       <p>Unless
                                 the query prolog contains a default namespace declaration or an import schema declaration
                                 defining the <termref def="dt-default-namespace-elements-and-types"/> as being
                                 <code nobreak="false">fixed</code>, the <termref def="dt-default-namespace-elements-and-types"/> 
                                 in the static context of the constructor expression is set to <var>U</var>.</p>
                                    </item>
                                 </olist>
                              </p>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>It is a <termref def="dt-static-error">static error</termref>
                           <errorref class="ST" code="0070"/> if a namespace declaration
                attribute attempts to do any of the following:
                <olist>
                              <item>
                                 <p>Bind the prefix <code nobreak="false">xml</code> to some namespace URI
                      other than <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
                   </p>
                              </item>
                              <item>
                                 <p>Bind a prefix other than <code nobreak="false">xml</code> to the namespace
                      URI <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
                   </p>
                              </item>
                              <item>
                                 <p>Bind the prefix <code nobreak="false">xmlns</code> to any namespace URI.
                   </p>
                              </item>
                              <item>
                                 <p>Bind a prefix to the namespace
                      URI <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.
                   </p>
                              </item>
                           </olist>
                        </p>
                     </item>
                  </olist>
                  <p> A namespace declaration attribute does not cause an attribute node to be created. </p>
                  <p>The following examples illustrate namespace declaration attributes:</p>
                  <ulist>
                     <item>
                        <p>In this element constructor, a namespace declaration attribute
                        is used to set the default namespace
                        to <code nobreak="false">http://example.org/animals</code>:<eg role="parse-test" xml:space="preserve">&lt;cat xmlns="http://example.org/animals"&gt;
  &lt;breed&gt;{ variety/@name }&lt;/breed&gt;
&lt;/cat&gt;</eg>
                        </p>
                        <p diff="add" at="2023-10-16">More specifically:</p>
                        <ulist>
                           <item>
                              <p>The expanded name of the constructed element will be 
                           <code nobreak="false">Q{http://example.org/animals}cat</code>.</p>
                           </item>
                           <item>
                              <p>The constructed element will have the
                           <termref def="dt-default-in-scope-namespace"/>
                                 <code nobreak="false">http://example.org/animals</code>.</p>
                           </item>
                           <item>
                              <p>The static context for evaluation of any expressions within the
                        element constructor will include a binding of the empty prefix
                        to the namespace URI <code nobreak="false">http://example.org/animals</code>. This ensures
                        that the nested <code nobreak="false">breed</code> element will also be in the namespace
                           <code nobreak="false">http://example.org/animals</code>.</p>
                           </item>
                           <item>
                              <p>The <termref def="dt-default-namespace-elements-and-types"/>
                           within the element constructor will be <code nobreak="false">http://example.org/animals</code>,
                        which means that the element name <code nobreak="false">variety</code> is also interpreted
                        as being in this namespace. This effect may be unwanted, since the document
                        containing the context node may well use a different default namespace. 
                        In XQuery 4.0 this effect can
                        be prevented by declaring, in the query prolog, that the 
                           <termref def="dt-default-namespace-elements-and-types"/> is <code nobreak="false">fixed</code>.
                        Alternatively the path expression can be written <code nobreak="false">Q{}variety/@name</code>
                        to make it explicit that <code nobreak="false">variety</code> refers to a no-namespace element.</p>
                           </item>
                        </ulist>
                     </item>
                     <item>
                        <p>In this element constructor, namespace declaration attributes are used to bind the namespace prefixes <code nobreak="false">metric</code> and <code nobreak="false">english</code>:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;box xmlns:metric="http://example.org/metric/units"
     xmlns:english = "http://example.org/english/units"&gt;
  &lt;height&gt; &lt;metric:meters&gt;3&lt;/metric:meters&gt; &lt;/height&gt;
  &lt;width&gt; &lt;english:feet&gt;6&lt;/english:feet&gt; &lt;/width&gt;
  &lt;depth&gt; &lt;english:inches&gt;18&lt;/english:inches&gt; &lt;/depth&gt;
&lt;/box&gt;</eg>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-content">
                  <head>Content</head>
                  <p>The part of a direct element constructor between the start tag and the end tag is called the <term>content</term> of the element constructor. This content may consist of text characters (parsed as <nt def="prod-xquery40-ElementContentChar">ElementContentChar<!--$spec = xquery40--></nt>), nested direct constructors, <nt def="prod-xquery40-CDataSection">CDataSections<!--$spec = xquery40--></nt>, character and <termref def="dt-predefined-entity-reference">predefined entity references</termref>, and <termref def="dt-enclosed-expression">enclosed expressions</termref>. In general, the value of an enclosed expression may be any sequence of nodes and/or atomic items. Enclosed expressions can be used in the content of an element  constructor to compute both the content and the attributes of the constructed node.</p>
                  <p>Conceptually, the content of an element constructor is processed as
follows:</p>
                  <olist>
                     <item>
                        <p>The content is evaluated to produce a
sequence of nodes called the <term>content sequence</term>, as
follows:</p>
                        <olist>
                           <item>
                              <p>If the <termref def="dt-boundary-space-policy">boundary-space policy</termref> in the <termref def="dt-static-context">static context</termref> is <code nobreak="false">strip</code>, <termref def="dt-boundary-whitespace">boundary whitespace</termref> is identified and deleted (see <specref ref="id-whitespace"/> for the definition of boundary whitespace.)</p>
                           </item>
                           <item>
                              <p>
                                 <termref def="dt-predefined-entity-reference">Predefined entity references</termref>
and <termref def="dt-character-reference">character references</termref> are expanded into their
referenced strings, as described in <specref ref="id-literals"/>. Characters inside a <nt def="prod-xquery40-CDataSection">CDataSection<!--$spec = xquery40--></nt>, including special characters such as <code nobreak="false">&lt;</code> and <code nobreak="false">&amp;</code>, are treated as literal characters rather than as markup characters (except for the sequence <code nobreak="false">]]&gt;</code>, which terminates the CDataSection).</p>
                           </item>
                           <item>
                              <p>Each consecutive sequence of
literal characters evaluates to a single text node containing the
characters.</p>
                           </item>
                           <item>
                              <p>Each nested direct constructor is evaluated according to the rules in <specref ref="id-element-constructor"/> or <specref ref="id-otherConstructors"/>, resulting in a new element, comment, or processing instruction node. Then:</p>
                              <olist>
                                 <item>
                                    <p>The <code nobreak="false">parent</code> property of the resulting node is then set to the newly constructed element node.</p>
                                 </item>
                                 <item>
                                    <p>The <code nobreak="false">base-uri</code> property of the
resulting node, and of each of its descendants, is set to be the same as that
of its new parent, unless it (the child node) has an <code nobreak="false">xml:base</code> attribute, in
which case its <code nobreak="false">base-uri</code> property is set to the value of that attribute,
<termref def="dt-resolve-relative-uri">resolved (if it is relative)</termref> against the <code nobreak="false">base-uri</code> property of its new parent
node.</p>
                                 </item>
                              </olist>
                           </item>
                           <item>
                              <p>Enclosed expressions are evaluated as follows: </p>
                              <olist>
                                 <item>
                                    <p>Each array returned by the enclosed expression is flattened by calling the function <code nobreak="false">array:flatten()</code> before the steps that follow.</p>
                                 </item>
                                 <item>
                                    <p>If an enclosed expression returns a <termref def="dt-function-item"/>, a type error is raised <errorref class="TY" code="0105"/>.</p>
                                 </item>
                                 <item>
                                    <p>For each adjacent sequence of one or more atomic items returned by an enclosed expression, a new text node is constructed, containing the result of casting each atomic item to a string, with a single space character inserted between adjacent values.</p>
                                    <note>
                                       <p>The insertion of blank characters between adjacent values applies even if one or both of the values is a zero-length string.</p>
                                    </note>
                                 </item>
                                 <item>
                                    <p>For each node returned by an enclosed expression, a new copy is made of the given node and all nodes that have the given node as an ancestor,  collectively referred to as <term>copied nodes</term>. The properties of the copied nodes are as follows:</p>
                                    <olist>
                                       <item>
                                          <p>Each copied node receives a new node identity.</p>
                                       </item>
                                       <item>
                                          <p>The <code nobreak="false">parent</code>, <code nobreak="false">children</code>, and <code nobreak="false">attributes</code> properties of the copied nodes are set so as to preserve their inter-node relationships. For the topmost node (the node directly returned by the enclosed expression), the <code nobreak="false">parent</code> property is set to the node constructed by this constructor.</p>
                                       </item>
                                       <item>
                                          <p>If <termref def="dt-construction-mode">construction mode</termref> in the <termref def="dt-static-context">static context</termref> is <code nobreak="false">strip</code>:</p>
                                          <olist>
                                             <item>
                                                <p>If the copied node is an element node, its <termref def="dt-type-annotation">type annotation</termref> is set to  <code nobreak="false">xs:untyped</code>. Its <code nobreak="false">nilled</code>, <code nobreak="false">is-id</code>, and <code nobreak="false">is-idrefs</code> properties are set to <code nobreak="false">false</code>.</p>
                                             </item>
                                             <item>
                                                <p>If the copied node is an attribute node, its <code nobreak="false">type-name</code> property  is set to <code nobreak="false">xs:untypedAtomic</code>. Its <code nobreak="false">is-idrefs</code> property is set to <code nobreak="false">false</code>. Its <code nobreak="false">is-id</code> property is set to <code nobreak="false">true</code> if the qualified name of the attribute node is <code nobreak="false">xml:id</code>; otherwise it is set to <code nobreak="false">false</code>.</p>
                                             </item>
                                             <item>
                                                <p>The <code nobreak="false">string-value</code> of each copied element and attribute node remains unchanged, and its <code nobreak="false">typed-value</code> becomes equal to its <code nobreak="false">string-value</code> as an instance of <code nobreak="false">xs:untypedAtomic</code>.<note>
                                                      <p> Implementations that store only the <termref def="dt-typed-value">typed value</termref> of a node are required at this point to convert the typed value to a string form.</p>
                                                   </note>
                                                </p>
                                             </item>
                                          </olist>
                                          <p>On the other hand, if <termref def="dt-construction-mode">construction mode</termref> in the <termref def="dt-static-context">static context</termref> is <code nobreak="false">preserve</code>, the <code nobreak="false">type-name</code>, <code nobreak="false">nilled</code>, 
                                          <code nobreak="false">string-value</code>, <code nobreak="false">typed-value</code>, <code nobreak="false">is-id</code>, and <code nobreak="false">is-idrefs</code> 
                                          properties of the copied nodes are preserved.</p>
                                       </item>
                                       <item>
                                          <p>The <termref def="dt-in-scope-namespaces"/> property of a copied element node is
                                          determined by the following rules. In applying these rules, the 
                                          <termref def="dt-default-in-scope-namespace"/>
                                          or absence of a default in-scope namespace is treated like any other
                                          <termref def="dt-namespace-binding"/>:</p>
                                          <olist>
                                             <item>
                                                <p>If <termref def="dt-copy-namespaces-mode">copy-namespaces mode</termref> specifies <code nobreak="false">preserve</code>, 
                                                all <termref def="dt-in-scope-namespaces"/> of the original element are
                                                   retained in the new copy.
                                                   If <termref def="dt-copy-namespaces-mode">copy-namespaces mode</termref> specifies <code nobreak="false">no-preserve</code>, 
                                                the new copy retains only those in-scope namespaces of the original 
                                                element that are used in the names of the element and its
                                                 attributes.</p>
                                             </item>
                                             <item>
                                                <p>If <termref def="dt-copy-namespaces-mode">copy-namespaces mode</termref> specifies <code nobreak="false">inherit</code>, 
                                                the copied node inherits all the <termref def="dt-in-scope-namespaces"/> of the constructed node,
                                                augmented and overridden by the in-scope namespaces of the original element 
                                                that were preserved by the preceding rule. If <termref def="dt-copy-namespaces-mode">copy-namespaces mode</termref> specifies <code nobreak="false">no-inherit</code>, 
                                                the copied node does not inherit any in-scope namespaces from the constructed node.</p>
                                             </item>
                                          </olist>
                                       </item>
                                       <item>
                                          <p>An enclosed expression in the content of an element constructor may cause 
                                          one or more existing nodes to be copied. Type error
                                          <errorref class="TY" code="0086"/>
                                          is raised in the following cases:</p>
                                          <olist>
                                             <item>
                                                <p>
                                                An element node is copied, and the
                                                <termref def="dt-typed-value">typed value</termref> of the element node 
                                                or one of its attributes is
                                                <termref def="dt-namespace-sensitive">namespace-sensitive</termref>,
                                                and <termref def="dt-construction-mode">construction mode</termref>
                                                is <code nobreak="false">preserve</code>, and
                                                <termref def="dt-copy-namespaces-mode">copy-namespaces mode</termref>
                                                is <code nobreak="false">no-preserve</code>.
                                                </p>
                                             </item>
                                             <item>
                                                <p>
An attribute node is copied but its parent element node is not
copied, and the <termref def="dt-typed-value">typed value</termref>
of the copied attribute node is
<termref def="dt-namespace-sensitive">namespace-sensitive</termref>,
and <termref def="dt-construction-mode">construction mode</termref>
is <code nobreak="false">preserve</code>.</p>
                                             </item>
                                          </olist>
                                          <note>
                                             <p>
                The rationale for error <errorref class="TY" code="0086"/> is as follows:
                It is not possible to preserve the type of a QName without also preserving
                the <termref def="dt-namespace-binding"/> that defines the prefix of the QName.</p>
                                          </note>
                                       </item>
                                       <item>
                                          <p>When an element or processing instruction node is copied, its <code nobreak="false">base-uri</code>
property is set to be the same as that of its new parent,
with the following exception: if a copied element node has an <code nobreak="false">xml:base</code> attribute, its <code nobreak="false">base-uri</code> property is set to
the value of that attribute, <termref def="dt-resolve-relative-uri">resolved (if it is relative)</termref> against
the <code nobreak="false">base-uri</code> property of the new parent node.</p>
                                       </item>
                                       <item>
                                          <p>All other properties of the copied nodes are preserved.</p>
                                       </item>
                                    </olist>
                                 </item>
                              </olist>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p> If the content sequence contains a document node, the document node is replaced in the content sequence by its children.</p>
                     </item>
                     <item>
                        <p>Adjacent text nodes in the content sequence are merged into a single text node by concatenating their contents, with no intervening blanks. After concatenation, any text node whose content is a zero-length string is deleted from the content sequence.</p>
                     </item>
                     <item>
                        <p>If the content sequence contains an attribute node or a
namespace node following a node that is not an attribute node or a
namespace node, a <termref def="dt-type-error">type error</termref> is
raised <errorref class="TY" code="0024"/>.</p>
                     </item>
                     <item>
                        <p>The properties of the newly constructed element node are determined as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <code nobreak="false">node-name</code> is the <termref def="dt-expanded-qname">expanded QName</termref> resulting from resolving the element name in the start tag, including its original namespace prefix (if any), as described in <specref ref="id-element-constructor"/>.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">parent</code> is set to empty.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">attributes</code> consist of all the attributes specified in the start tag as described in <specref ref="id-attributes"/>, together with all the attribute nodes in the content sequence, in <termref def="dt-implementation-dependent">implementation-dependent</termref> order. Note that the <code nobreak="false">parent</code> property of each of these attribute nodes has been set to the newly constructed element node. If two or more attributes have the same <code nobreak="false">node-name</code>,  a <termref def="dt-dynamic-error">dynamic error</termref> is raised <errorref class="DY" code="0025"/>. If an attribute named <code nobreak="false">xml:space</code> has a value other than <code nobreak="false">preserve</code> or <code nobreak="false">default</code>, a <termref def="dt-dynamic-error">dynamic error</termref>  may be raised <errorref code="0092" class="DY"/>.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">children</code> consist of all the element, text, comment, and processing
   instruction nodes in the content sequence. Note that the <code nobreak="false">parent</code> property of each of these nodes has been set to the newly constructed element node.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">base-uri</code> is set to the following value:</p>
                              <olist>
                                 <item>
                                    <p>If the constructed node has an attribute named <code nobreak="false">xml:base</code>, then the value of this attribute, <termref def="dt-resolve-relative-uri">resolved (if it is relative)</termref> against the
                                       <phrase diff="chg" at="2023-05-19">
                                          <termref def="dt-executable-base-uri"/>
                                       </phrase>, as described in
                                       <specref ref="id-resolve-relative-uri"/>. </p>
                                 </item>
                                 <item>
                                    <p>Otherwise,
                                       the <phrase diff="chg" at="2023-05-19">
                                          <termref def="dt-executable-base-uri"/>
                                       </phrase>.</p>
                                 </item>
                              </olist>
                           </item>
                           <item>
                              <p>
                              The <termref def="dt-in-scope-namespaces"/> comprise all 
                              the <termref def="dt-namespace-binding">namespace bindings</termref> 
                              resulting from namespace declaration attributes as described in <specref ref="id-namespaces"/>, and possibly additional namespace bindings as described in <specref ref="id-ns-nodes-on-elements"/>.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">nilled</code> property is <code nobreak="false">false</code>.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">string-value</code> property is equal to the concatenated contents of the text-node descendants in document order. If there are no text-node descendants, the <code nobreak="false">string-value</code> property is a zero-length string.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">typed-value</code> property is equal to the <code nobreak="false">string-value</code> property, as an instance of <code nobreak="false">xs:untypedAtomic</code>.</p>
                           </item>
                           <item role="xquery">
                              <p>If <termref def="dt-construction-mode">construction mode</termref> in the <termref def="dt-static-context">static context</termref> is <code nobreak="false">strip</code>, 
                              the <code nobreak="false">type-name</code> property is <code nobreak="false">xs:untyped</code>. 
                              On the other hand, if construction mode is <code nobreak="false">preserve</code>, 
                              the <code nobreak="false">type-name</code> property is <code nobreak="false">xs:anyType</code>.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">is-id</code> and <code nobreak="false">is-idrefs</code> properties are both <code nobreak="false">false</code>.</p>
                           </item>
                        </olist>
                     </item>
                  </olist>
                  <ulist>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;a&gt;{ 1 }&lt;/a&gt;</eg>
                        <p>The constructed element node has one child, a text node containing the value <code nobreak="false">"1"</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;a&gt;{ 1, 2, 3 }&lt;/a&gt;</eg>
                        <p>The constructed element node has one child, a text node containing the value <code nobreak="false">"1 2 3"</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;c&gt;{ 1 }{ 2 }{ 3 }&lt;/c&gt;</eg>
                        <p>The constructed element node has one child, a text node containing the value <code nobreak="false">"123"</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;b&gt;{ 1, "2", "3" }&lt;/b&gt;</eg>
                        <p>The constructed element node has one child, a text node containing the value <code nobreak="false">"1 2 3"</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;fact&gt;I saw 8 cats.&lt;/fact&gt;</eg>
                        <p>The constructed element node has one child, a text node containing the value <code nobreak="false">"I saw 8 cats."</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;fact&gt;I saw { 5 + 3 } cats.&lt;/fact&gt;</eg>
                        <p>The constructed element node has one child, a text node containing the value <code nobreak="false">"I saw 8 cats."</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;fact&gt;I saw &lt;howmany&gt;{ 5 + 3 }&lt;/howmany&gt; cats.&lt;/fact&gt;</eg>
                        <p>The constructed element node has three children: a text node containing
                        <code nobreak="false">"I saw </code> ", a child element node named <code nobreak="false">howmany</code>,
                        and a text node containing <code nobreak="false">" cats."</code>. The child element node
                        in turn has a single text node child containing the value <code nobreak="false">"8"</code>.</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-whitespace">
                  <head>Boundary Whitespace</head>
                  <p>In a direct element constructor, whitespace characters may appear in the content of the constructed element. In some cases, enclosed expressions and/or nested elements may be separated only by whitespace characters.   For
example, in the expression below, the end-tag
<code nobreak="false">&lt;/title&gt;</code> and the start-tag <code nobreak="false">&lt;author&gt;</code> are separated by a newline character and four space
characters:</p>
                  <eg role="parse-test" xml:space="preserve">&lt;book isbn="isbn-0060229357"&gt;
  &lt;title&gt;Harold and the Purple Crayon&lt;/title&gt;
  &lt;author&gt;
    &lt;first&gt;Crockett&lt;/first&gt;
    &lt;last&gt;Johnson&lt;/last&gt;
  &lt;/author&gt;
&lt;/book&gt;</eg>
                  <p>
                     <termdef term="boundary whitespace" id="dt-boundary-whitespace">
                        <term>Boundary whitespace</term> is a
sequence of consecutive whitespace characters within the content of a <termref def="dt-direct-elem-const">direct element constructor</termref>, that is delimited at each end either by the start or
end of the content, or by a <nt def="prod-xquery40-DirectConstructor">DirectConstructor<!--$spec = xquery40--></nt>, or by an <nt def="doc-xquery40-EnclosedExpr">EnclosedExpr<!--$spec = xquery40--></nt>. For this purpose, characters generated by
   <termref def="dt-character-reference">character references</termref> such as <code nobreak="false">&amp;#x20;</code> or by <nt def="prod-xquery40-CDataSection">CDataSections<!--$spec = xquery40--></nt> are not
   considered to be whitespace characters.</termdef>
                  </p>
                  <p>The <termref def="dt-boundary-space-policy">boundary-space policy</termref> in the <termref def="dt-static-context">static context</termref> controls whether boundary whitespace is
   preserved by element constructors. If boundary-space policy is <code nobreak="false">strip</code>, boundary whitespace is not considered significant and
   is discarded. On the other hand, if boundary-space policy is <code nobreak="false">preserve</code>, boundary whitespace is
   considered significant and is
   preserved.</p>
                  <ulist>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;cat&gt;
  &lt;breed&gt;{ $b }&lt;/breed&gt;
  &lt;color&gt;{ $c }&lt;/color&gt;
&lt;/cat&gt;</eg>
                        <p>The constructed
   <code nobreak="false">cat</code> element node has two child element nodes named
   <code nobreak="false">breed</code> and <code nobreak="false">color</code>. Whitespace surrounding
   the child elements will be stripped away by the element
   constructor if boundary-space policy is
   <code nobreak="false">strip</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;a&gt; { "abc" } &lt;/a&gt;</eg>
                        <p>If
   boundary-space policy is <code nobreak="false">strip</code>, this example is equivalent to <code role="parse-test" nobreak="false">&lt;a&gt;abc&lt;/a&gt;</code>. However, if
   boundary-space policy is <code nobreak="false">preserve</code>, this example is
   equivalent to <code role="parse-test" nobreak="false">&lt;a&gt;  abc  &lt;/a&gt;</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;a&gt; z { "abc" }&lt;/a&gt;</eg>
                        <p>Since the
   whitespace surrounding the <code nobreak="false">z</code> is not boundary
   whitespace, it is always preserved. This example is equivalent to
   <code role="parse-test" nobreak="false">&lt;a&gt; z abc&lt;/a&gt;</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;a&gt;&amp;#x20;{ "abc" }&lt;/a&gt;</eg>
                        <p>This
   example is equivalent to <code role="parse-test" nobreak="false">&lt;a&gt; abc&lt;/a&gt;</code>, regardless
   of the boundary-space policy, because the space generated by the <termref def="dt-character-reference">character reference</termref> is not treated as a whitespace character.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;a&gt;{ "  " }&lt;/a&gt;</eg>
                        <p>This example constructs an element containing two space characters,
   regardless of the boundary-space policy, because whitespace inside an enclosed expression is never considered to be boundary whitespace.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">&lt;a&gt;{ [ "one", "little", "fish" ] }&lt;/a&gt;</eg>
                        <p>This example constructs an element containing the text <code nobreak="false">one little fish</code>, because the array is flattened, and the resulting sequence of atomic items is converted to a text node with a single blank between values.</p>
                     </item>
                  </ulist>
                  <note>
                     <p>Element constructors treat attributes named <code nobreak="false">xml:space</code> as ordinary attributes. An <code nobreak="false">xml:space</code> attribute does not affect the handling of whitespace by an element constructor.</p>
                  </note>
               </div4>
            </div3>
            <div3 id="id-otherConstructors" role="xquery">
               <head>Other Direct Constructors</head>
               <p>XQuery allows an expression to generate a processing instruction node or a comment node. This can be accomplished by using a <term>direct processing instruction constructor</term> or a <term>direct comment constructor</term>. In each case, the syntax of the constructor expression is
based on the syntax of a similar construct in XML.</p>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-DirPIConstructor">
                     <lhs>DirPIConstructor</lhs>
                     <rhs>"&lt;?"  <nt def="prod-xquery40-PITarget">PITarget<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-DirPIContents">DirPIContents<!--$idref_lang_part = xquery40- --></nt>)?  "?&gt;"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-DirPIConstructor-PITarget">
                     <lhs>PITarget</lhs>
                     <rhs>
                        <xnt ref="NT-PITarget" spec="XML">[http://www.w3.org/TR/REC-xml#NT-PITarget]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-DirPIConstructor-S">
                     <lhs>S</lhs>
                     <rhs>
                        <xnt ref="NT-S" spec="XML">[http://www.w3.org/TR/REC-xml#NT-S]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-DirPIConstructor-DirPIContents">
                     <lhs>DirPIContents</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* '?&gt;' Char*))</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="doc-xquery40-DirPIConstructor-Char">
                     <lhs>Char</lhs>
                     <rhs>
                        <xnt ref="NT-Char" spec="XML">[http://www.w3.org/TR/REC-xml#NT-Char]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>
               </scrap>
               <p>A direct processing instruction constructor creates a processing instruction node whose <code nobreak="false">target</code> property is <nt def="prod-xquery40-PITarget">PITarget<!--$spec = xquery40--></nt> and whose <code nobreak="false">content</code> property is <nt def="prod-xquery40-DirPIContents">DirPIContents<!--$spec = xquery40--></nt>. The <code nobreak="false">base-uri</code> property of the node is empty.  The <code nobreak="false">parent</code> property of the node is empty.</p>
               <p>The <nt def="prod-xquery40-PITarget">PITarget<!--$spec = xquery40--></nt> of a processing instruction must not consist of the characters <code nobreak="false">XML</code> in any combination of upper and lower case,
               <phrase diff="add" at="B">and must not contain a colon</phrase>. The <nt def="prod-xquery40-DirPIContents">DirPIContents<!--$spec = xquery40--></nt> of a processing instruction must not contain the string <code nobreak="false">"?&gt;"</code>.</p>
               <p>The following example illustrates a direct processing instruction constructor:</p>
               <eg role="parse-test" xml:space="preserve">&lt;?format role="output" ?&gt;</eg>
               <p>A direct comment constructor creates a comment node whose  <code nobreak="false">content</code> property is <nt def="prod-xquery40-DirCommentContents">DirCommentContents<!--$spec = xquery40--></nt>. Its <code nobreak="false">parent</code> property is empty.</p>
               <p>The <nt def="prod-xquery40-DirCommentContents">DirCommentContents<!--$spec = xquery40--></nt> of a comment must not contain two consecutive hyphens or end with a hyphen. These rules are syntactically enforced by the grammar shown above.</p>
               <p>The following example illustrates a direct comment constructor:</p>
               <eg role="parse-test" xml:space="preserve">&lt;!-- Tags are ignored in the following section --&gt;</eg>
               <note>
                  <p>A direct comment constructor is different from a <nt def="doc-xquery40-Comment">comment<!--$spec = xquery40--></nt>, since a direct comment constructor actually constructs a comment node, whereas a <nt def="doc-xquery40-Comment">comment<!--$spec = xquery40--></nt> is simply used in documenting a query and is not evaluated.</p>
               </note>
            </div3>
            <div3 id="id-computedConstructors">
               <head>Computed Constructors</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-ComputedConstructor">
                     <lhs>ComputedConstructor</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CompDocConstructor">CompDocConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompElemConstructor">CompElemConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompAttrConstructor">CompAttrConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompNamespaceConstructor">CompNamespaceConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompTextConstructor">CompTextConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompCommentConstructor">CompCommentConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompPIConstructor">CompPIConstructor<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ComputedConstructor-CompDocConstructor">
                     <lhs>CompDocConstructor</lhs>
                     <rhs>"document"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ComputedConstructor-CompElemConstructor">
                     <lhs>CompElemConstructor</lhs>
                     <rhs>"element"  <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedContentExpr">EnclosedContentExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ComputedConstructor-CompAttrConstructor">
                     <lhs>CompAttrConstructor</lhs>
                     <rhs>"attribute"  <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ComputedConstructor-CompNamespaceConstructor">
                     <lhs>CompNamespaceConstructor</lhs>
                     <rhs>"namespace"  <nt def="prod-xquery40-CompNodeNCName">CompNodeNCName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ComputedConstructor-CompTextConstructor">
                     <lhs>CompTextConstructor</lhs>
                     <rhs>"text"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ComputedConstructor-CompCommentConstructor">
                     <lhs>CompCommentConstructor</lhs>
                     <rhs>"comment"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ComputedConstructor-CompPIConstructor">
                     <lhs>CompPIConstructor</lhs>
                     <rhs>"processing-instruction"  <nt def="prod-xquery40-CompNodeNCName">CompNodeNCName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>
                  <phrase role="xquery">An alternative way to create nodes is by using a <term id="term-elem-ctor">computed constructor</term>.</phrase> A computed
constructor begins with a keyword that identifies the type of node to
be created: <code nobreak="false">element</code>, <code nobreak="false">attribute</code>,
<code nobreak="false">document</code>, <code nobreak="false">text</code>,
<code nobreak="false">processing-instruction</code>, <code nobreak="false">comment</code>, or
<code nobreak="false">namespace</code>.</p>
               <p>For those kinds of nodes that have names (element, attribute, 
processing instruction, and namespace nodes), the keyword that specifies the node
kind is followed by the name of the node to be created. This name may

be specified either as a literal or as an expression enclosed in
braces. <termdef term="name expression" id="dt-name-expression">When

an expression is used to specify the name of a constructed node, that
expression is called the <term>name expression</term> of the
constructor.</termdef>
               </p>
               <p>The following example illustrates the use of computed element and
attribute constructors in a simple case where the names of the
constructed nodes are constants<phrase role="xquery">. This example generates exactly the
same result as the first example in <specref ref="id-element-constructor"/>
                  </phrase>:</p>
               <eg role="parse-test" xml:space="preserve">element #book {
  attribute #isbn { "isbn-0060229357" },
  element #title { "Harold and the Purple Crayon" },
  element #author {
    element #first { "Crockett" },
    element #last { "Johnson" }
  }
}</eg>
               <note>
                  <p>In the above example, the element names <code nobreak="false">#book</code>,<code nobreak="false">#title</code>, and so on
            are <nt def="doc-xquery40-QNameLiteral">QNameLiteral<!--$spec = xquery40--></nt>s, which are expanded using the
                  <termref def="dt-constructed-element-namespace-rule"/>.
            The attribute name <code nobreak="false">#isbn</code>, by contrast, is expanded using the
            <termref def="dt-no-namespace-rule"/>.</p>
               </note>
               <note role="xquery">
                  <p>XQuery 4.0 allows the node name to be written as a QName literal
            (for example, <code nobreak="false">element #book {}</code>, and at the same
            time it disallows the use of a defined set of language keywords
            without quotes: for example <code nobreak="false">element div {}</code> was allowed
            in XQuery 3.1 but must now be written <code nobreak="false">element #div {}</code> or
            <code nobreak="false">element { "div" } {}</code>. The reason for this incompatible
            change is that allowing map constructors to omit the <code nobreak="false">map</code>
            keyword would otherwise create an ambiguity: consider for example the
            expression <code nobreak="false">element otherwise {}</code>.</p>
                  <p>The list of reserved keywords is given at 
               <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                          href="#parse-note-unreserved-name"
                          xlink:type="simple"
                          xlink:show="replace"
                          xlink:actuate="onRequest">Constraint: unreserved-name</loc>.</p>
                  <p>Because the list of reserved keywords may be extended in future
            versions of this specification, the safest strategy is to always use
            the <code nobreak="false">QNameLiteral</code> syntax (for example <code nobreak="false">element #div</code>).
            To avoid any dependency on the default namespace context, the form
            <code nobreak="false">element Q{}div</code> might also be used.</p>
                  <p>To write code that is portable between XQuery 3.1 and XQuery 4.0,
            the best advice is to use either the form <code nobreak="false">element { "div" }</code>
            or the form <code nobreak="false">element Q{}div</code>.</p>
               </note>
               <div4 id="id-computedElements">
                  <head>Computed Element Constructors</head>
                  <changes role="xquery">
                     <change issue="1450 1528 1983" PR="1480 1989 2481" date="2024-10-03">
                     When the element name matches a language keyword such as <code nobreak="false">div</code> or <code nobreak="false">value</code>, 
                     it must now be written as a QName literal. This is a backwards incompatible change.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-CompElemConstructor">
                        <lhs>CompElemConstructor</lhs>
                        <rhs>"element"  <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-EnclosedContentExpr">EnclosedContentExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompElemConstructor-CompNodeName">
                        <lhs>CompNodeName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-UnreservedName">UnreservedName<!--$idref_lang_part = xquery40- --></nt>  |  ("{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompElemConstructor-QNameLiteral">
                        <lhs>QNameLiteral</lhs>
                        <rhs>"#"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompElemConstructor-UnreservedName">
                        <lhs>UnreservedName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#parse-note-unreserved-name">xgc: unreserved-name</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-CompElemConstructor-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompElemConstructor-Expr">
                        <lhs>Expr</lhs>
                        <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompElemConstructor-EnclosedContentExpr">
                        <lhs>EnclosedContentExpr</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompElemConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>
                     <termdef term="computed element constructor" id="dt-computed-elem-const">A <term>computed element constructor</term> creates an element node, allowing both the name 
                     and the content of the node to be dynamically computed.</termdef>
                  </p>
                  <p>The element name is determined by the <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$spec = xquery40--></nt>, which 
                  may be provided in a number of ways:</p>
                  <olist>
                     <item>
                        <p>As a QName literal, for example:</p>
                        <slist>
                           <sitem>
                              <code nobreak="false">element #table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element #html:table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element #Q{}table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element #Q{http://http://www.w3.org/1999/xhtml}table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element #Q{http://http://www.w3.org/1999/xhtml}html:table {}</code>
                           </sitem>
                        </slist>
                        <p>A QName literal written as an unprefixed <termref def="dt-qname">lexical QName</termref>
                     (the first form above) is resolved using the 
                     <termref def="dt-constructed-element-namespace-rule"/>. This differs from the normal rules for evaluating
                     a QName literal as an atomic item of type <code nobreak="false">xs:QName</code>.</p>
                        <p>Note that the third and fourth examples (<code nobreak="false">#Q{}table</code> and 
                        <code nobreak="false">#Q{http://http://www.w3.org/1999/xhtml}table</code>) will result in the name of the
                     constructed element having no prefix, which may in turn trigger the generation of a default
                     namespace declaration.</p>
                     </item>
                     <item role="xquery">
                        <p>As a simple <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt>, for example:</p>
                        <slist>
                           <sitem>
                              <code nobreak="false">element table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element html:table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element Q{}table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element Q{http://http://www.w3.org/1999/xhtml}table {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">element Q{http://http://www.w3.org/1999/xhtml}html:table {}</code>
                           </sitem>
                        </slist>
                        <p>In XQuery 4.0 the first form (using an unprefixed <termref def="dt-qname">lexical QName</termref>)
                     is allowed only if the element name is not a reserved keyword (such as <code nobreak="false">div</code> or <code nobreak="false">case</code>): see
                  <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                                href="#parse-note-unreserved-name"
                                xlink:type="simple"
                                xlink:show="replace"
                                xlink:actuate="onRequest">unreserved-name</loc>. In all other cases,
                     the effect is exactly the same as when a leading <code nobreak="false">#</code>
                     is added to turn the EQName into a QName literal.</p>
                        <p>This syntax is retained for compatibility, but is deprecated.</p>
                     </item>
                     <item>
                        <p>As an expression in curly brackets. This is processed as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <termref def="dt-atomization">Atomization</termref> is applied to the value of the <termref def="dt-name-expression">name expression</termref>. If the result of atomization is not a single atomic item of type <code nobreak="false">xs:QName</code>, <code nobreak="false">xs:string</code>, or <code nobreak="false">xs:untypedAtomic</code>, a <termref def="dt-type-error">type
   error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                           </item>
                           <item>
                              <p>If the atomized value of the <termref def="dt-name-expression">name expression</termref> is of type
   <code nobreak="false">xs:QName</code>, that <termref def="dt-expanded-qname">expanded QName</termref> is used as the <code nobreak="false">node-name</code> property of the constructed
   element, retaining the prefix part of the QName.</p>
                           </item>
                           <item>
                              <p>If the atomized value of the <termref def="dt-name-expression">name expression</termref> is of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>, 
                        that value is converted to an <termref def="dt-expanded-qname">expanded QName</termref>
                                 <phrase diff="add" at="A">as follows:</phrase>
                              </p>
                              <olist>
                                 <item>
                                    <p>Leading and trailing whitespace is removed.</p>
                                 </item>
                                 <item>
                                    <p>If the value is a lexical QName, it is expanded
                           using the <termref def="dt-constructed-element-namespace-rule"/>.</p>
                                 </item>
                                 <item>
                                    <p>If the value is in the form of a <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$spec = xquery40--></nt>
                           (<code nobreak="false">Q{uri}local</code> or <code nobreak="false">Q{uri}prefix:local</code>), it
                           is converted to an <termref def="dt-expanded-qname"/> with the supplied namespace URI and
                           local name, and with the specified prefix if present.</p>
                                 </item>
                              </olist>
                              <note role="xquery">
                                 <p>This was under-specified in XQuery 3.1.</p>
                              </note>
                           </item>
                           <item>
                              <p>If conversion of the atomized <termref def="dt-name-expression">name expression</termref> to an <termref def="dt-expanded-qname">expanded QName</termref> is not successful, a <termref def="dt-dynamic-error">dynamic error</termref> is raised <errorref class="DY" code="0074"/>.</p>
                           </item>
                        </olist>
                     </item>
                  </olist>
                  <p>The resulting <termref def="dt-expanded-qname">expanded QName</termref> is used as the
                        <code nobreak="false">node-name</code> property of the constructed element, retaining the prefix part of the QName
                        <phrase diff="add" at="A">(or its absence)</phrase>.</p>
                  <!--	<change diff="add" at="XQ.E19"> -->
                  <p>An error is raised
             <errorref class="DY" code="0096"/> if the node-name of the constructed
             element node has any of the following properties:
          </p>
                  <ulist>
                     <item>
                        <p>Its namespace prefix is <code nobreak="false">xmlns</code>.
             </p>
                     </item>
                     <item>
                        <p>Its namespace URI is <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.
             </p>
                     </item>
                     <item>
                        <p>Its namespace prefix is <code nobreak="false">xml</code> and its namespace
                URI is not <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
             </p>
                     </item>
                     <item>
                        <p>Its namespace prefix is other than <code nobreak="false">xml</code> and its
                namespace URI is <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
             </p>
                     </item>
                  </ulist>
                  <p>The above error <rfc2119>may</rfc2119> be raised as a <termref def="dt-static-error"/> if
               the element name is computed statically; in other cases it <rfc2119>must</rfc2119> 
                  be raised as a <termref def="dt-dynamic-error"/>.</p>
                  <p role="xquery">The <termref def="dt-content-expression">content expression</termref> of a computed element constructor (if present) is processed 
                  in exactly the same way as an enclosed expression in the content of a <termref def="dt-direct-elem-const">direct element constructor</termref>, as described in Step 1e of <specref ref="id-content"/>. The result of processing the content expression is a sequence of nodes called the 
                  <term>content sequence</term>. If the <termref def="dt-content-expression">content expression</termref> is absent, the content sequence is the empty sequence.</p>
                  <p>Processing of the computed element constructor proceeds as follows:</p>
                  <olist>
                     <item>
                        <p>If the content sequence contains a document node, the document node is replaced in the 
                        content sequence by its children.</p>
                     </item>
                     <item>
                        <p>Adjacent text nodes in the content sequence are merged into a single text 
                        node by concatenating their contents, with no intervening blanks. After concatenation, 
                        any text node whose content is a zero-length string is deleted from the content sequence.</p>
                     </item>
                     <item>
                        <p> If the content
   sequence contains an attribute node or a namespace node following a node that is not an
   attribute node or a namespace node, a <termref def="dt-type-error">type error</termref>
   is raised <errorref class="TY" code="0024"/>.</p>
                     </item>
                     <item>
                        <p>The properties of the newly constructed element node are determined as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <code nobreak="false">node-name</code> is the <termref def="dt-expanded-qname">expanded QName</termref> resulting from processing the specified 
                              <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$spec = xquery40--></nt>, as described above.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">parent</code> is empty.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">attributes</code> consist of all the attribute nodes in the content sequence, in <termref def="dt-implementation-dependent">implementation-dependent</termref> order. Note that the <code nobreak="false">parent</code> property of each of these attribute nodes has been set to the newly constructed element node. If two or more  attributes have the same <code nobreak="false">node-name</code>,  a <termref def="dt-dynamic-error">dynamic error</termref> is raised <errorref class="DY" code="0025"/>. If an attribute named <code nobreak="false">xml:space</code> has a value other than <code nobreak="false">preserve</code> or <code nobreak="false">default</code>, a <termref def="dt-dynamic-error">dynamic error</termref>  may be raised <errorref code="0092" class="DY"/>.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">children</code> consist of all the element, text, comment, and processing
                               instruction nodes in the content sequence. Note that the <code nobreak="false">parent</code> property 
                              of each of these nodes has been set to the newly constructed element node.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">base-uri</code> is set to the following value:

                              <olist>
                                    <item>
                                       <p>If the constructed node has an attribute named <code nobreak="false">xml:base</code>, 
                                       then the value of this attribute, <termref def="dt-resolve-relative-uri">resolved (if it is relative)</termref> against the 
                                       <phrase diff="chg" at="2023-05-19">
                                             <termref def="dt-executable-base-uri"/>
                                          </phrase>, as described
                                       in <specref ref="id-resolve-relative-uri"/>.</p>
                                    </item>
                                    <item>
                                       <p>Otherwise, the <phrase diff="chg" at="2023-05-19">
                                             <termref def="dt-executable-base-uri"/>
                                          </phrase>.</p>
                                    </item>
                                 </olist>
                              </p>
                           </item>
                           <item>
                              <p>
                              The <termref def="dt-in-scope-namespaces"/> are computed as described in <specref ref="id-ns-nodes-on-elements"/>.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">nilled</code> property is <code nobreak="false">false</code>.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">string-value</code> property is equal to the concatenated contents 
                              of the text-node descendants in document order.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">typed-value</code> property is equal to the <code nobreak="false">string-value</code> 
                              property, as an instance of <code nobreak="false">xs:untypedAtomic</code>.</p>
                           </item>
                           <item role="xquery">
                              <p>If <termref def="dt-construction-mode">construction mode</termref> in the <termref def="dt-static-context">static context</termref> is <code nobreak="false">strip</code>, the <code nobreak="false">type-name</code> 
                              property is <code nobreak="false">xs:untyped</code>. On the other hand, if construction mode is 
                              <code nobreak="false">preserve</code>, the <code nobreak="false">type-name</code> property is <code nobreak="false">xs:anyType</code>.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">is-id</code> and <code nobreak="false">is-idrefs</code> properties are set to <code nobreak="false">false</code>.</p>
                           </item>
                        </olist>
                     </item>
                  </olist>
                  <p>A computed element constructor might be
                  used to make a modified copy of an existing element. For example,
                  if the variable <code nobreak="false">$e</code> is bound to an element with <termref def="dt-numeric">numeric</termref>
                  content, the following constructor might be used to create a new
                  element with the same name and attributes as <code nobreak="false">$e</code> and
                  with numeric content equal to twice the value of
                  <code nobreak="false">$e</code>:</p>
                  <eg role="parse-test" xml:space="preserve">element { node-name($e) } { $e/@*, 2 * data($e) }</eg>
                  <p>In this example, if <code nobreak="false">$e</code> is
                  bound by the expression <code nobreak="false">let $e := &lt;length
                  units="inches"&gt;{ 5 }&lt;/length&gt;</code>, then the result of the
                  example expression is the element <code nobreak="false">&lt;length
                  units="inches"&gt;10&lt;/length&gt;</code>.</p>
                  <!--<note>
                  <p>The <termref def="dt-static-type">static type</termref> of the expression <code
                        role="parse-test"
                        >fn:node-name($e)</code> is <code>xs:QName?</code>, denoting zero or one QName. 
                     The example can be successfully evaluated as written provided that 
                     <code>$e</code> is bound to exactly one element node with numeric content.</p>
               </note>-->
                  <p>One important
                  purpose of computed constructors is to allow the name of a node to
                  be computed. We will illustrate this feature by an expression that
                  translates the name of an element from one language to
                  another. Suppose that the variable <code nobreak="false">$dict</code> is bound to a
                  <code nobreak="false">dictionary</code> element containing a sequence of <code nobreak="false">entry</code> elements, 
                  each of which encodes translations for a specific word.  Here is an example
                  entry that encodes the German and Italian variants of the word “address”:</p>
                  <eg role="parse-test" xml:space="preserve">
&lt;entry word="address"&gt;
  &lt;variant xml:lang="de"&gt;Adresse&lt;/variant&gt;
  &lt;variant xml:lang="it"&gt;indirizzo&lt;/variant&gt;
&lt;/entry&gt;
</eg>
                  <p>Suppose further that the variable <code nobreak="false">$e</code> is bound to the following element:</p>
                  <eg role="parse-test" xml:space="preserve">&lt;address&gt;123 Roosevelt Ave. Flushing, NY 11368&lt;/address&gt;</eg>
                  <p>Then the following expression generates a new element in which the name of <code nobreak="false">$e</code> has been translated into Italian and the content of <code nobreak="false">$e</code> (including its attributes, if any) has been preserved. The first enclosed expression after the <code nobreak="false">element</code> keyword generates the name of the element, and the second enclosed
expression generates the content and attributes:</p>
                  <eg role="parse-test" xml:space="preserve">
element {
  $dict/entry[@word = name($e)]/variant[@xml:lang = "it"]
} {
  $e/@*, $e/node()
}</eg>
                  <p>The result of this expression is as follows:</p>
                  <eg role="parse-test" xml:space="preserve">&lt;indirizzo&gt;123 Roosevelt Ave. Flushing, NY 11368&lt;/indirizzo&gt;</eg>
               </div4>
               <div4 id="id-computedAttributes">
                  <head>Computed Attribute Constructors</head>
                  <changes role="xquery">
                     <change issue="1450 1528 1983" PR="1480 1989 2481" date="2024-10-03">
                     When the attribute name matches a language keyword such as <code nobreak="false">for</code> or <code nobreak="false">to</code>, 
                     it must now be written as a QName literal. This is a backwards incompatible change.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-CompAttrConstructor">
                        <lhs>CompAttrConstructor</lhs>
                        <rhs>"attribute"  <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompAttrConstructor-CompNodeName">
                        <lhs>CompNodeName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-UnreservedName">UnreservedName<!--$idref_lang_part = xquery40- --></nt>  |  ("{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompAttrConstructor-QNameLiteral">
                        <lhs>QNameLiteral</lhs>
                        <rhs>"#"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompAttrConstructor-UnreservedName">
                        <lhs>UnreservedName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#parse-note-unreserved-name">xgc: unreserved-name</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-CompAttrConstructor-EQName">
                        <lhs>EQName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompAttrConstructor-Expr">
                        <lhs>Expr</lhs>
                        <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompAttrConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>A computed attribute constructor creates a new attribute node,
                with its own node identity.</p>
                  <p>Attributes have no default namespace. The rules that expand attribute names create an  <termref def="dt-implementation-dependent">implementation-dependent</termref> prefix if an attribute name has a namespace URI but no prefix is provided.</p>
                  <p>The attribute name may be provided in a number of ways:</p>
                  <olist>
                     <item>
                        <p>As a QName literal, for example:</p>
                        <slist>
                           <sitem>
                              <code nobreak="false">attribute #width {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute #xsi:type {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute #Q{}width {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute #Q{http://www.w3.org/2001/XMLSchema-instance}xsi:type {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute #Q{http://www.w3.org/2001/XMLSchema-instance}type {}</code>
                           </sitem>
                        </slist>
                        <p>A QName literal written as an unprefixed <termref def="dt-qname">lexical QName</termref>
                     (the first form above) is resolved using the 
                     <termref def="dt-no-namespace-rule"/>.</p>
                        <p>Note that the last example (<code nobreak="false">#Q{http://www.w3.org/2001/XMLSchema-instance}type</code>) 
                        will result in the name of the
                     constructed attribute having a system-generated prefix.</p>
                     </item>
                     <item role="xquery">
                        <p>As a simple <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt>, for example:</p>
                        <slist>
                           <sitem>
                              <code nobreak="false">attribute width {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute xsi:type {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute Q{}width {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute Q{http://www.w3.org/2001/XMLSchema-instance}xsi:type {}</code>
                           </sitem>
                           <sitem>
                              <code nobreak="false">attribute Q{http://www.w3.org/2001/XMLSchema-instance}type {}</code>
                           </sitem>
                        </slist>
                        <p>In XQuery 4.0 the first form (using an unprefixed <termref def="dt-qname">lexical QName</termref>)
                     is allowed only if the attribute name is not a reserved keyword (such as <code nobreak="false">div</code> or <code nobreak="false">value</code>): see
                  <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                                href="#parse-note-unreserved-name"
                                xlink:type="simple"
                                xlink:show="replace"
                                xlink:actuate="onRequest">unreserved-name</loc>. In all other cases,
                     the effect is exactly the same as when a leading <code nobreak="false">#</code>
                     is added to turn the EQName into a QName literal.</p>
                        <p>This syntax is retained for compatibility, but is deprecated.</p>
                     </item>
                     <item>
                        <p>As an expression in curly brackets. This is processed as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <termref def="dt-atomization">Atomization</termref> is applied to the result of the <termref def="dt-name-expression">name expression</termref>. If the result of <termref def="dt-atomization">atomization</termref> is not a
                            single atomic item of type <code nobreak="false">xs:QName</code>,
                            <code nobreak="false">xs:string</code>, or <code nobreak="false">xs:untypedAtomic</code>, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                           </item>
                           <item>
                              <p>If the atomized value of the <termref def="dt-name-expression">name expression</termref> is of type <code nobreak="false">xs:QName</code>:</p>
                              <olist>
                                 <item>
                                    <p>If the <termref def="dt-expanded-qname">expanded QName</termref> returned by the atomized name expression has a namespace URI 
                                 but has no prefix, it is given an <termref def="dt-implementation-dependent">implementation-dependent</termref> prefix.</p>
                                 </item>
                                 <item>
                                    <p>The resulting <termref def="dt-expanded-qname">expanded QName</termref> (including its prefix) is used as the <code nobreak="false">node-name</code> property of the constructed
                                 attribute node.</p>
                                 </item>
                              </olist>
                           </item>
                           <item>
                              <p>If the atomized value of the <termref def="dt-name-expression">name expression</termref> is of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>, 
                        that value is converted to an <termref def="dt-expanded-qname">expanded QName</termref>
                                 <phrase diff="add" at="A">as follows:</phrase>
                              </p>
                              <olist>
                                 <item>
                                    <p>Leading and trailing whitespace is removed.</p>
                                 </item>
                                 <item>
                                    <p>If the value is a lexical QName, it is expanded
                           using the <termref def="dt-no-namespace-rule"/>.</p>
                                 </item>
                                 <item>
                                    <p>If the value is in the form of a <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$spec = xquery40--></nt> 
                           (<code nobreak="false">Q{uri}local</code> or <code nobreak="false">Q{uri}prefix:local</code>), it
                           is converted to an <termref def="dt-expanded-qname"/> with the supplied namespace URI,
                           local name, and prefix, or with an <termref def="dt-implementation-dependent"/> prefix
                           if none is supplied.</p>
                                 </item>
                                 <item>
                                    <p>If conversion of the atomized name expression to an <termref def="dt-expanded-qname"/> is not successful, 
                           a dynamic error is raised <errorref class="DY" code="0074"/>.</p>
                                 </item>
                              </olist>
                              <note role="xquery">
                                 <p>This was under-specified in XQuery 3.1.</p>
                              </note>
                           </item>
                        </olist>
                     </item>
                  </olist>
                  <p>The resulting <termref def="dt-expanded-qname">expanded QName</termref> (including its
   prefix) is used as the <code nobreak="false">node-name</code> property of the
   constructed attribute node. If expansion of the QName is not
   successful, a <termref def="dt-static-error">static error</termref>
   is raised <errorref code="0081" class="ST"/>.</p>
                  <p>If the keyword <code nobreak="false">attribute</code> is followed by a <termref def="dt-name-expression">name expression</termref>, the name
   expression is processed as follows:</p>
                  <!--	<change diff="chg" at="XQ.E19"> -->
                  <p>A <termref def="dt-dynamic-error">dynamic error</termref> is raised
             <errorref class="DY" code="0044"/> if the node-name of the constructed
             attribute node has any of the following properties:
          </p>
                  <ulist>
                     <item>
                        <p>Its namespace prefix is <code nobreak="false">xmlns</code>.
             </p>
                     </item>
                     <item>
                        <p>It has no namespace prefix and its local name is
                <code nobreak="false">xmlns</code>.
             </p>
                     </item>
                     <item>
                        <p>Its namespace URI is <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.
             </p>
                     </item>
                     <item>
                        <p>Its namespace prefix is <code nobreak="false">xml</code> and its namespace
                URI is not <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
             </p>
                     </item>
                     <item>
                        <p>Its namespace prefix is other than <code nobreak="false">xml</code> and its
                namespace URI is <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
             </p>
                     </item>
                  </ulist>
                  <!--	</change> -->
                  <p>The <termref def="dt-content-expression">content
   expression</termref> of a computed attribute constructor is
   processed as follows:</p>
                  <olist>
                     <item>
                        <p>
                           <termref def="dt-atomization">Atomization</termref> is
     applied to the result of the <termref def="dt-content-expression">content expression</termref>,
     converting it to a sequence of atomic items. (If the <termref def="dt-content-expression">content expression</termref> is
     absent, the result of this step is the empty
     sequence.)</p>
                     </item>
                     <item>
                        <p>If the result of atomization is the empty sequence, the
     value of the attribute is the zero-length string. Otherwise, each
     atomic item in the atomized sequence is cast into a
     string.</p>
                     </item>
                     <item>
                        <p>The individual strings resulting from the previous step
     are merged into a single string by concatenating them with a
     single space character between each pair. The resulting string
     becomes the <code nobreak="false">string-value</code> property of the new
     attribute node. The <termref def="dt-type-annotation">type
     annotation</termref> (<code nobreak="false">type-name</code> property) of the new
     attribute node is <code nobreak="false">xs:untypedAtomic</code>. The
     <code nobreak="false">typed-value</code> property of the attribute node is the
     same as its <code nobreak="false">string-value</code>, as an instance of
     <code nobreak="false">xs:untypedAtomic</code>.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">parent</code> property of the attribute node
     is set to empty.</p>
                     </item>
                     <item>
                        <p>If the attribute name is <code nobreak="false">xml:id</code>, then
     <code nobreak="false">xml:id</code> processing is performed as defined in <bibref ref="XMLID"/>. This ensures that the attribute node has the type
     <code nobreak="false">xs:ID</code> and that its value is properly normalized. If
     an error is encountered during <code nobreak="false">xml:id</code> processing, an
     implementation may raise a <termref def="dt-dynamic-error">dynamic error</termref>
                           <errorref class="DY" code="0091"/>.</p>
                     </item>
                     <item>
                        <p>If the attribute name is <code nobreak="false">xml:id</code>, the
     <code nobreak="false">is-id</code> property of the resulting attribute node is
     set to <code nobreak="false">true</code>; otherwise the <code nobreak="false">is-id</code>
     property is set to <code nobreak="false">false</code>. The <code nobreak="false">is-idrefs</code>
     property of the attribute node is unconditionally set to
     <code nobreak="false">false</code>.</p>
                     </item>
                     <item>
                        <p>If the attribute name is <code nobreak="false">xml:space</code> and the
     attribute value is other than <code nobreak="false">preserve</code> or
     <code nobreak="false">default</code>, a <termref def="dt-dynamic-error">dynamic error</termref>  may be raised <errorref code="0092" class="DY"/>.</p>
                     </item>
                  </olist>
                  <ulist>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">attribute #size { 4 + 3 }</eg>
                        <p>The <termref def="dt-string-value">string
     value</termref> of the <code nobreak="false">size</code> attribute is
     <code nobreak="false">"7"</code> and its type is
     <code nobreak="false">xs:untypedAtomic</code>.</p>
                     </item>
                     <item>
                        <p>Example:</p>
                        <eg role="parse-test" xml:space="preserve">
attribute {
  if ($sex = "M") then #husband else #wife
} {
  &lt;a&gt;Hello&lt;/a&gt;, 1 to 3, &lt;b&gt;Goodbye&lt;/b&gt;
}
</eg>
                        <p>The name of the constructed attribute is
     either <code nobreak="false">husband</code> or
     <code nobreak="false">wife</code> (in no namespace). Its <termref def="dt-string-value">string
     value</termref> is "<code nobreak="false">Hello 1 2 3
     Goodbye</code>".</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-documentConstructors">
                  <head>Document Node Constructors</head>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-CompDocConstructor">
                        <lhs>CompDocConstructor</lhs>
                        <rhs>"document"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompDocConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>
                     <phrase role="xquery">All document node constructors are computed constructors. </phrase>
                  The result of a document node constructor is a new document node, with its own node identity.</p>
                  <p>A document node constructor is useful when the result of a query is to be a document 
                  in its own right. The following example illustrates a query that returns an XML document 
                  containing a root element named <code nobreak="false">author-list</code>:</p>
                  <eg role="parse-test" xml:space="preserve">document {
  &lt;author-list&gt;{
    doc("bib.xml")/bib/book/author
  }&lt;/author-list&gt;
}</eg>
                  <p>The <termref def="dt-content-expression">content expression</termref> of a document node constructor is processed 
                  in exactly the same way as the content expression of a computed element constructor,
                  as described in <specref ref="id-computedElements"/>.</p>
                  <!--an enclosed expression in the content of a <termref
                     def="dt-direct-elem-const"
                     >direct element constructor</termref>, as described in Step 1e of <specref
                     ref="id-content"
                     />. 
               -->
                  <p>The result of processing the content expression is a sequence of nodes 
                  called the <term>content sequence</term>. Processing of the document node 
                  constructor then proceeds as follows:</p>
                  <olist>
                     <item>
                        <p>If the content sequence contains a document node, the document node 
                        is replaced in the content sequence by its children.</p>
                     </item>
                     <item>
                        <p>Adjacent text nodes in the content sequence are merged into a single 
                        text node by concatenating their contents, with no intervening blanks. 
                        After concatenation, any text node whose content is a zero-length string 
                        is deleted from the content sequence.</p>
                     </item>
                     <item>
                        <p> If the content sequence contains an attribute node, a
<termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                     </item>
                     <item>
                        <p> If the content sequence contains a namespace node, a
<termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                     </item>
                     <item>
                        <p>The properties of the newly constructed document node are determined as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <code nobreak="false">base-uri</code> is
    set to the <phrase diff="chg" at="2023-05-19">
                                    <termref def="dt-executable-base-uri"/>
                                 </phrase>.</p>
                           </item>
                           <item>
                              <p>
                                 <code nobreak="false">children</code> consist of all the element, text, comment, and processing
   instruction nodes in the content sequence. Note that the <code nobreak="false">parent</code> property of each of these nodes has been set to the newly constructed document node.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">unparsed-entities</code> and <code nobreak="false">document-uri</code> properties are empty.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">string-value</code> property is equal to the concatenated contents of the text-node descendants in document order.</p>
                           </item>
                           <item>
                              <p>The <code nobreak="false">typed-value</code> property is equal to the <code nobreak="false">string-value</code> property, as an instance of <code nobreak="false">xs:untypedAtomic</code>.</p>
                           </item>
                        </olist>
                     </item>
                  </olist>
                  <p>No validation is performed on the constructed document node. The <bibref ref="XML"/> rules that govern the structure of an XML document (for example, the 
                  document node must have exactly one child that is an element node)  
                  are not enforced by the XQuery 4.0 document node constructor.</p>
               </div4>
               <div4 id="id-textConstructors">
                  <head>Text Node Constructors</head>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-CompTextConstructor">
                        <lhs>CompTextConstructor</lhs>
                        <rhs>"text"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompTextConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>
                     <phrase role="xquery">All text node constructors are computed constructors. </phrase>
                  The result of a text node constructor is a new text node, with its own node identity.</p>
                  <p>The <termref def="dt-content-expression">content expression</termref> of a text node constructor is processed as follows:</p>
                  <olist>
                     <item>
                        <p>
                           <termref def="dt-atomization">Atomization</termref> is applied to the value of the <termref def="dt-content-expression">content expression</termref>, converting it to a sequence of atomic items.</p>
                     </item>
                     <item>
                        <p>If the result of atomization is the empty sequence, no text node is constructed. 
                        Otherwise, each atomic item in the atomized sequence is cast into a string.</p>
                     </item>
                     <item>
                        <p>The individual strings resulting from the previous step are merged into 
                        a single string by concatenating them with a single space character between 
                        each pair. The resulting string becomes the <code nobreak="false">content</code> property of 
                        the constructed text node.</p>
                     </item>
                  </olist>
                  <p>The <code nobreak="false">parent</code> property of the constructed text node is set to empty.</p>
                  <note>
                     <p>It is possible for a text node constructor to construct a text node containing 
                     a zero-length string. However, if used in the content of a constructed element 
                     or document node, such a text node will be deleted or merged with another text node.</p>
                  </note>
                  <p>The following example illustrates a text node constructor:</p>
                  <eg role="parse-test" xml:space="preserve">text { "Hello" }</eg>
                  <note>
                     <p>It is possible to construct a text node whose string value is zero-length. The rules 
                     for constructing element nodes, however, ensure that a zero-length text node will be discarded
                     if used while forming the content of an element.</p>
                  </note>
               </div4>
               <div4 id="id-computed-pis">
                  <head>Computed Processing Instruction Constructors</head>
                  <changes role="xquery">
                     <change issue="1512 2027" PR="1513 2028" date="2024-10-18">
                     When the processing instruction name matches a language keyword such as <code nobreak="false">try</code> or <code nobreak="false">validate</code>, 
                     it must now be written with a preceding <code nobreak="false">#</code> character. This is a backwards incompatible change.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-CompPIConstructor">
                        <lhs>CompPIConstructor</lhs>
                        <rhs>"processing-instruction"  <nt def="prod-xquery40-CompNodeNCName">CompNodeNCName<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompPIConstructor-CompNodeNCName">
                        <lhs>CompNodeNCName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-MarkedNCName">MarkedNCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-UnreservedNCName">UnreservedNCName<!--$idref_lang_part = xquery40- --></nt>  |  ("{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompPIConstructor-MarkedNCName">
                        <lhs>MarkedNCName</lhs>
                        <rhs>"#"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompPIConstructor-UnreservedNCName">
                        <lhs>UnreservedNCName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#parse-note-unreserved-name">xgc: unreserved-name</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-CompPIConstructor-Expr">
                        <lhs>Expr</lhs>
                        <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompPIConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>A computed processing instruction constructor (<nt def="doc-xquery40-CompPIConstructor">CompPIConstructor<!--$spec = xquery40--></nt>) constructs a new processing instruction node with its own node identity.
   </p>
                  <p>The name of a processing instruction node is always an NCName, and may be provided in a number of ways:</p>
                  <olist>
                     <item>
                        <p>As an <code nobreak="false">NCName</code> with a preceding <code nobreak="false">#</code> sign, 
                     for example <code nobreak="false">processing-instruction #xref {}</code>.
                  </p>
                     </item>
                     <item role="xquery">
                        <p>As a simple <code nobreak="false">NCName</code> without the preceding <code nobreak="false">#</code>, 
                     for example <code nobreak="false">processing-instruction xref {}</code>. This
                  form is allowed only if the name is not a reserved keyword: see
                  <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                                href="#parse-note-unreserved-name"
                                xlink:type="simple"
                                xlink:show="replace"
                                xlink:actuate="onRequest">unreserved-name</loc>.</p>
                     </item>
                     <item>
                        <p>As an expression in curly braces. This is processed as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <termref def="dt-atomization">Atomization</termref> is applied to the value of the <termref def="dt-name-expression">name expression</termref>. If the result of <termref def="dt-atomization">atomization</termref> is not a single atomic item of type <code nobreak="false">xs:NCName</code>, 
                              <code nobreak="false">xs:string</code>, or <code nobreak="false">xs:untypedAtomic</code>, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                           </item>
                           <item>
                              <p>If the atomized value of the <termref def="dt-name-expression">name expression</termref> is of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>, 
                              that value is cast to the type <code nobreak="false">xs:NCName</code>. If the value cannot be cast to <code nobreak="false">xs:NCName</code>, a <termref def="dt-dynamic-error">dynamic error</termref> is raised <errorref class="DY" code="0041"/>.</p>
                           </item>
                           <item>
                              <p>The resulting NCName is then used as the <code nobreak="false">target</code> property of the newly constructed 
                              processing instruction node. However, a <termref def="dt-dynamic-error">dynamic error</termref> is raised if the  NCName is equal to <code nobreak="false">"XML"</code> (in any combination of upper and lower case) <errorref class="DY" code="0064"/>.</p>
                           </item>
                        </olist>
                     </item>
                  </olist>
                  <p>The
   <termref def="dt-content-expression">content expression</termref> of a computed processing instruction constructor
   is processed as follows:</p>
                  <olist>
                     <item>
                        <p>
                           <termref def="dt-atomization">Atomization</termref> is applied to the value of the <termref def="dt-content-expression">content expression</termref>, converting it to a sequence of atomic items. (If the <termref def="dt-content-expression">content expression</termref> is absent, the result of this step is the empty sequence.)</p>
                     </item>
                     <item>
                        <p>If the result of atomization is the empty sequence, it is replaced by a zero-length string.
                        Otherwise, each atomic item in the atomized sequence is cast into a string.
                        If any of the resulting strings contains the string <code nobreak="false">"?&gt;"</code>, a <termref def="dt-dynamic-error">dynamic error</termref>
                           <errorref class="DY" code="0026"/> is raised.</p>
                     </item>
                     <item>
                        <p>The individual strings resulting from the previous step are merged into a single string by
                        concatenating them with a single space character between each pair.
                        Leading whitespace is removed from the resulting string. The resulting string then
                        becomes the <code nobreak="false">content</code> property of the constructed processing instruction node.</p>
                     </item>
                  </olist>
                  <p>The remaining properties of the new processing instruction node are determined as follows:</p>
                  <olist>
                     <item>
                        <p>The <code nobreak="false">parent</code> property is empty.</p>
                     </item>
                     <item>
                        <p>The <code nobreak="false">base-uri</code> property is empty.</p>
                     </item>
                  </olist>
                  <p>The following example illustrates a computed processing instruction constructor:</p>
                  <eg role="parse-test" xml:space="preserve">let $target := "audio-output",
return processing-instruction { $target } { "beep" }</eg>
                  <p>The processing instruction node constructed by this example might be serialized as follows:</p>
                  <eg xml:space="preserve">&lt;?audio-output beep?&gt;</eg>
               </div4>
               <div4 id="id-computed-comments">
                  <head>Computed Comment Constructors</head>
                  <scrap headstyle="show">
                     <head/>
                     <prod id="doc-xquery40-CompCommentConstructor">
                        <lhs>CompCommentConstructor</lhs>
                        <rhs>"comment"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompCommentConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>A computed comment constructor (<nt def="doc-xquery40-CompCommentConstructor">CompCommentConstructor<!--$spec = xquery40--></nt>) constructs a new comment node with its own node identity.
   The <termref def="dt-content-expression">content expression</termref> of a computed comment constructor is processed as follows:</p>
                  <olist>
                     <item>
                        <p>
                           <termref def="dt-atomization">Atomization</termref> is applied to the value of the <termref def="dt-content-expression">content expression</termref>, converting it to a sequence of atomic items.</p>
                     </item>
                     <item>
                        <p>If the result of atomization is the empty sequence, it is replaced by a zero-length string. Otherwise, each atomic item in the atomized sequence is cast into a string.</p>
                     </item>
                     <item>
                        <p>The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. The resulting string becomes the <code nobreak="false">content</code> property of the constructed comment node.</p>
                     </item>
                     <item>
                        <p>It is a <termref def="dt-dynamic-error">dynamic
 error</termref>
                           <errorref class="DY" code="0072"/> if the result of the <termref def="dt-content-expression">content expression</termref> of a computed comment constructor contains two adjacent hyphens or ends with a hyphen.</p>
                     </item>
                  </olist>
                  <p>The <code nobreak="false">parent</code> property of the constructed comment node is set to empty.</p>
                  <p>The following example illustrates a computed comment constructor:</p>
                  <eg role="parse-test" xml:space="preserve">let $homebase := "Houston"
return comment { concat($homebase, ", we have a problem.") }</eg>
                  <p>The comment node constructed by this example might be serialized as follows:</p>
                  <eg xml:space="preserve">&lt;!--Houston, we have a problem.--&gt;</eg>
               </div4>
               <div4 id="id-computed-namespaces">
                  <head>Computed Namespace Constructors</head>
                  <changes role="xquery">
                     <change issue="1512 2027" PR="1513 2028" date="2024-10-18">
                     When the namespace prefix matches a language keyword such as <code nobreak="false">as</code> or <code nobreak="false">at</code>, 
                     it must now be written with a preceding <code nobreak="false">#</code> character. This is a backwards incompatible change.
                  </change>
                  </changes>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-CompNamespaceConstructor">
                        <lhs>CompNamespaceConstructor</lhs>
                        <rhs>"namespace"  <nt def="prod-xquery40-CompNodeNCName">CompNodeNCName<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompNamespaceConstructor-CompNodeNCName">
                        <lhs>CompNodeNCName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-MarkedNCName">MarkedNCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-UnreservedNCName">UnreservedNCName<!--$idref_lang_part = xquery40- --></nt>  |  ("{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompNamespaceConstructor-MarkedNCName">
                        <lhs>MarkedNCName</lhs>
                        <rhs>"#"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-CompNamespaceConstructor-UnreservedNCName">
                        <lhs>UnreservedNCName</lhs>
                        <rhs>
                           <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                        <com>
                           <loc href="#parse-note-unreserved-name">xgc: unreserved-name</loc>
                        </com>
                     </prod>

                     <prod id="doc-xquery40-CompNamespaceConstructor-Expr">
                        <lhs>Expr</lhs>
                        <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                     </prod>

                     <prod id="doc-xquery40-CompNamespaceConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>A computed namespace constructor creates a new namespace node,
   with its own node identity. The parent of the newly created
   namespace node is absent.</p>
                  <p>The name of a namespace node is always an <code nobreak="false">NCName</code>, and represents
               the namespace prefix.</p>
                  <p>The string value of a namespace node should be a <code nobreak="false">URI</code>, and represents
               the namespace URI.</p>
                  <p>The namespace prefix may be provided in a number of ways:</p>
                  <olist>
                     <item>
                        <p>As an <code nobreak="false">NCName</code> with a preceding <code nobreak="false">#</code> sign, 
                     for example <code nobreak="false">namespace #xlink { "http://www.w3.org/1999/xlink" }</code>.
                  </p>
                     </item>
                     <item>
                        <p>As a simple <code nobreak="false">NCName</code> with no preceding <code nobreak="false">#</code> sign, 
                     for example <code nobreak="false">namespace xlink { "http://www.w3.org/1999/xlink" }</code>. This
                  form is allowed only if the namespace prefix is not a reserved keyword: see
                  <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                                href="#parse-note-unreserved-name"
                                xlink:type="simple"
                                xlink:show="replace"
                                xlink:actuate="onRequest">unreserved-name</loc>.</p>
                     </item>
                     <item>
                        <p>As an expression in curly braces. This is processed as follows:</p>
                        <olist>
                           <item>
                              <p>
                                 <termref def="dt-atomization">Atomization</termref> is
      applied to the result of the enclosed expression.</p>
                           </item>
                           <item>
                              <p>
      If the result of <termref def="dt-atomization">atomization</termref>
        is the empty sequence
        or a single atomic item of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>,
      then the following rules are applied in order:</p>
                              <olist>
                                 <item>
                                    <p>If the result is castable to <code nobreak="false">xs:NCName</code>, then it is used as the local name
         of the newly constructed namespace node. (The local name of a namespace node
         represents the prefix part of the <termref def="dt-namespace-binding"/>.)</p>
                                 </item>
                                 <item>
                                    <p>If the result is the empty sequence
                      or a zero-length <code nobreak="false">xs:string</code>
                      or <code nobreak="false">xs:untypedAtomic</code> item,
               the new namespace node has no name (such a namespace node represents a binding for the default namespace).</p>
                                 </item>
                                 <item>
                                    <p>Otherwise, a <termref def="dt-dynamic-error">dynamic error</termref>  is raised  <errorref class="DY" code="0074"/>.</p>
                                 </item>
                              </olist>
                           </item>
                           <item>
                              <p>If the result of atomization is not the empty sequence
                               or a single atomic item of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>,
      a type error is raised <errorref class="TY" code="0004"/>.</p>
                           </item>
                        </olist>
                     </item>
                  </olist>
                  <p>The <termref def="dt-content-expression">content expression</termref> is evaluated, and the result is cast
    to <code nobreak="false">xs:anyURI</code> to create the <code nobreak="false">URI</code> property
    for the newly created node.  
    An implementation may raise a <termref def="dt-dynamic-error">dynamic error</termref>
                     <errorref class="DY" code="0074"/> if the <code nobreak="false">URIExpr</code> of a computed namespace constructor is not a valid instance of <code nobreak="false">xs:anyURI</code>.</p>
                  <p>An error <errorref class="DY" code="0101"/> is raised if a
    computed namespace constructor attempts to do any of the
    following:</p>
                  <ulist>
                     <item>
                        <p>Bind the prefix <code nobreak="false">xml</code> to some namespace URI
      other than <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
      </p>
                     </item>
                     <item>
                        <p>Bind a prefix other than <code nobreak="false">xml</code> to the namespace
      URI <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.
      </p>
                     </item>
                     <item>
                        <p>Bind the prefix <code nobreak="false">xmlns</code> to any namespace URI.
      </p>
                     </item>
                     <item>
                        <p>Bind a prefix to the namespace
      URI <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.
      </p>
                     </item>
                     <item>
                        <p>Bind any prefix (including the empty prefix) to a zero-length namespace URI.</p>
                     </item>
                  </ulist>
                  <p>By itself, a computed namespace constructor has no effect on
                  the <termref def="dt-in-scope-namespaces"/> of any element,
                  but if an element constructor’s content
                  sequence contains a namespace node, the <termref def="dt-namespace-binding"/> it
                  represents is added to that element’s <termref def="dt-in-scope-namespaces"/>.</p>
                  <p>A computed namespace constructor has no effect on the <termref def="dt-static-namespaces"/>
                  in the <termref def="dt-static-context"/>.</p>
                  <note>
                     <p>The newly created namespace node has all properties defined
      for a namespace node in the data model, but its parent is always absent.  As defined in the
      data model, the name of the node is the prefix, the string value
      of the node is the URI. Since the nodes are parentless, their relative order is implementation
      dependent.</p>
                  </note>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>A computed namespace constructor with a prefix:</p>
                        <eg role="parse-test" xml:space="preserve">namespace #a { "http://a.example.com" }</eg>
                     </item>
                     <item>
                        <p>A computed namespace constructor with a prefix expression:</p>
                        <eg role="parse-test" xml:space="preserve">namespace { "a" || $i } { "http://example.ns/a" || $i }</eg>
                     </item>
                     <item>
                        <p>A computed namespace constructor with the empty prefix:</p>
                        <eg role="parse-test" xml:space="preserve">namespace {""} { "http://example.ns/a0" }</eg>
                     </item>
                  </ulist>
                  <p>Computed namespace constructors are generally used to add to the
<termref def="dt-in-scope-namespaces"/> of elements created using computed element constructors:</p>
                  <eg role="parse-test" xml:space="preserve">
element #age {
  namespace #xmlns:xsi { "http://www.w3.org/2001/XMLSchema-instance" },
  namespace #xs { "http://www.w3.org/2001/XMLSchema" },
  attribute #xsi:type { "xs:integer" },
  23
}
</eg>
                  <p>In this example, the explicit construction of 
                  the <code nobreak="false">xsi</code>
                     <termref def="dt-namespace-binding"/> 
                  is unnecessary; it would be created automatically, because the <code nobreak="false">xsi</code> 
                  prefix is used in an attribute name. By contrast, the declaration of
                  the <code nobreak="false">xs</code>
                     <termref def="dt-namespace-binding"/> is needed; the attribute’s 
                  content is simply character data, and would not trigger automatic creation
                  of a namespace binding. This would be true even if the attribute is subsequently
                  validated against a schema that interprets <code nobreak="false">"xs:integer"</code> as a QName,
                  because such validation relies on the namespace binding already being present.</p>
                  <p role="xquery">Computed namespace constructors have no effect on the <termref def="dt-static-namespaces"/>
                  in the static context. 
                  If the prefix <code nobreak="false">a</code> is not already defined in the <termref def="dt-static-namespaces"/>, 
                  the following expression results in a static error
<errorref class="ST" code="0081"/>.</p>
                  <eg role="xquery" xml:space="preserve">
&lt;a:form&gt;{
  namespace a { "http://a.example.com" }
}&lt;/a:form&gt;
</eg>
                  <note>
                     <p>It is not possible to use a computed namespace constructor to
                    generate a namespace undeclaration such as <code nobreak="false">xmlns=""</code>
                 or (with XML Namespaces 1.1) <code nobreak="false">xmlns:p=""</code>. A namespace undeclaration in lexical XML
                 is represented in the XDM model by the absence of a <termref def="dt-namespace-binding"/> that
                 would otherwise be present.</p>
                  </note>
               </div4>
            </div3>
            <div3 id="id-ns-nodes-on-elements">
               <head>In-scope Namespaces of a Constructed Element</head>
               <p>An element node constructed by a <phrase role="xquery">direct or</phrase> computed element
constructor has an <termref def="dt-in-scope-namespaces"/> property that consists of a set of 
               <termref def="dt-namespace-binding">namespace bindings</termref>.  The
in-scope namespaces of an element node may affect the way the node is
serialized (see <specref ref="id-serialization"/>), and may also
affect the behavior of certain functions that operate on nodes, such
as <function>fn:name</function>. Note the difference between <termref def="dt-in-scope-namespaces">in-scope namespaces</termref>, which is a
dynamic property of an element node, and <termref def="dt-static-namespaces">statically known namespaces</termref>,
which is a static property of an expression.  One of
the namespace bindings in the in-scope namespaces may have an empty prefix:
this is referred to as the <termref def="dt-default-in-scope-namespace"/> of the element. The in-scope
namespaces of a constructed element node consist of the following
<termref def="dt-namespace-binding">namespace bindings</termref>:</p>
               <ulist>
                  <item role="xquery">
                     <p>A <termref def="dt-namespace-binding"/> is created for each namespace declared
                     in the current element constructor by a <termref def="dt-namespace-decl-attr">namespace declaration attribute</termref>.</p>
                  </item>
                  <item>
                     <p>A <termref def="dt-namespace-binding"/> is created for each namespace node in
                  the content sequence of the current element constructor.</p>
                  </item>
                  <item role="xquery">
                     <p>A <termref def="dt-namespace-binding"/> is created for each namespace that is
                    declared in a <termref def="dt-namespace-decl-attr">namespace declaration attribute</termref> of an enclosing <termref def="dt-direct-elem-const">direct element constructor</termref> and
                      not overridden by the current element constructor or an intermediate constructor.</p>
                  </item>
                  <item>
                     <p>A <termref def="dt-namespace-binding"/> is always created to bind the prefix
  <code nobreak="false">xml</code> to the namespace URI
  <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.</p>
                  </item>
                  <item>
                     <p>For each prefix used in the name of the
  constructed element or in the names of its attributes, a <termref def="dt-namespace-binding"/> must exist.</p>
                     <p>If a <termref def="dt-namespace-binding"/> does not already exist for one of these
  prefixes, a new namespace binding is created for it.</p>
                     <p>If this would result in a conflict, because it would require two
  different bindings of the same prefix, then the prefix used in the
  node name is changed to an arbitrary <termref def="dt-implementation-dependent">implementation-dependent</termref>
  prefix that does not cause such a conflict, and a <termref def="dt-namespace-binding"/>
  is created for this new prefix.</p>
                     <p>If there is a <termref def="dt-default-in-scope-namespace"/>, then 
                     a binding is created between the empty prefix and that URI.</p>
                  </item>
               </ulist>
               <note role="xquery">
                  <p>
                     <termref def="dt-copy-namespaces-mode">Copy-namespaces
mode</termref> does not affect the <termref def="dt-in-scope-namespaces"/> of a newly
constructed element node. It applies only to existing nodes that are
copied by a constructor expression.</p>
               </note>
               <p>In an element constructor, if two or more <termref def="dt-namespace-binding">namespace bindings</termref> in the
<termref def="dt-in-scope-namespaces"/> would have the same prefix, then an error is raised
if they have different URIs <errorref class="DY" code="0102"/>; if they
would have the same prefix and URI, duplicate bindings are
ignored. 
If the name of an element in an element constructor is in no namespace,
creating a default namespace for that element using a computed namespace constructor is an error <errorref class="DY" code="0102"/>. 
For instance, the following computed constructor raises an error because the element’s name is not in a namespace, 
but a default namespace is defined.</p>
               <eg role="parse-test" xml:space="preserve">element #Q{}e { namespace { '' } { 'u' } }</eg>
               <p>The following example illustrates the <termref def="dt-in-scope-namespaces"/> of a constructed element:</p>
               <eg role="xquery" xml:space="preserve">declare namespace p = "http://example.com/ns/p";
declare namespace q = "http://example.com/ns/q";
declare namespace f = "http://example.com/ns/f";
&lt;p:a q:b="{ f:func(2) }" xmlns:r="http://example.com/ns/r"/&gt;
</eg>
               <p role="xquery">Or equivalently, with a computed constructor:</p>
               <eg xml:space="preserve">declare namespace p = "http://example.com/ns/p";
declare namespace q = "http://example.com/ns/q";
declare namespace f = "http://example.com/ns/f";
element #p:a {
  attribute #q:b { f:func(2) }
  namespace #r {"http://example.com/ns/r"}
}  
</eg>
               <p>The <termref def="dt-in-scope-namespaces"/> of the resulting <code nobreak="false">p:a</code> element comprise 
               the following <termref def="dt-namespace-binding">namespace bindings</termref>:</p>
               <slist>
                  <sitem>
                     <code nobreak="false">p = "http://example.com/ns/p"</code>
                  </sitem>
                  <sitem>
                     <code nobreak="false">q = "http://example.com/ns/q"</code>
                  </sitem>
                  <sitem>
                     <code nobreak="false">r = "http://example.com/ns/r"</code>
                  </sitem>
                  <sitem>
                     <code nobreak="false">xml = "http://www.w3.org/XML/1998/namespace"</code>
                  </sitem>
               </slist>
               <p>The <termref def="dt-namespace-binding">namespace bindings</termref> for <code nobreak="false">p</code> and <code nobreak="false">q</code> 
               are added to the result element because their respective namespaces
               are used in the names of the element and its attributes. The namespace binding <code nobreak="false">r="http://example.com/ns/r"</code> 
               is added to the in-scope namespaces of the constructed
               element because it is explicitly created, even though it is not used in a name.</p>
               <p>No <termref def="dt-namespace-binding"/> corresponding to <code nobreak="false">f="http://example.com/ns/f"</code> is created, 
               because the namespace prefix <code nobreak="false">f</code> appears only in the query prolog and is not used in an element 
               or attribute name of the constructed node. This namespace binding does not appear in the query result, 
               even though it is present in the <termref def="dt-static-namespaces"/> and is available for use 
               during processing of the query.</p>
               <p role="xquery">Note that the following constructed element, if nested within a <code nobreak="false">validate</code> expression, cannot be validated:
</p>
               <eg role="xquery" xml:space="preserve">&lt;p xsi:type="xs:integer"&gt;3&lt;/p&gt;</eg>
               <p role="xquery">The constructed element will have <termref def="dt-namespace-binding">namespace bindings</termref> 
               for the prefixes <code nobreak="false">xsi</code> 
               (because it is used in a name) and <code nobreak="false">xml</code> (because it is defined for every 
               constructed element node). During validation of the constructed element, the validator 
               will be unable to interpret the namespace prefix <code nobreak="false">xs</code> because it is has 
               no namespace binding. Validation of this constructed element could be made possible 
               by providing a <termref def="dt-namespace-decl-attr">namespace declaration attribute</termref>, as in the following example:</p>
               <eg role="xquery" xml:space="preserve">&lt;p xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:integer"&gt;3&lt;/p&gt;</eg>
            </div3>
         </div2>
         <div2 id="id-flwor-expressions">
            <head>
               <phrase role="xquery">FLWOR Expressions</phrase>
            </head>
            <p role="xquery">XQuery provides a versatile expression called a FLWOR expression 
            that may contain multiple clauses. The FLWOR expression can be used for many purposes, 
            including iterating over sequences, joining multiple documents, and performing grouping 
            and aggregation. The name FLWOR, pronounced "flower", is suggested by the keywords 
            <code nobreak="false">for</code>, <code nobreak="false">let</code>, <code nobreak="false">where</code>, <code nobreak="false">order by</code>, 
            and <code nobreak="false">return</code>, which introduce some of the clauses used in FLWOR expressions 
            (but this is not a complete list of such clauses.)</p>
            <p role="xquery">The overall syntax of a FLWOR expression is shown here, and relevant parts 
            of the syntax are expanded in subsequent sections.</p>
            <scrap role="xquery" headstyle="show">
               <prod id="doc-xquery40-FLWORExpr">
                  <lhs>FLWORExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-InitialClause">InitialClause<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-IntermediateClause">IntermediateClause<!--$idref_lang_part = xquery40- --></nt>*  <nt def="prod-xquery40-ReturnClause">ReturnClause<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-InitialClause">
                  <lhs>InitialClause</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ForClause">ForClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetClause">LetClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-WindowClause">WindowClause<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-ForClause">
                  <lhs>ForClause</lhs>
                  <rhs>"for"  (<nt def="prod-xquery40-ForBinding">ForBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-LetClause">
                  <lhs>LetClause</lhs>
                  <rhs>"let"  (<nt def="prod-xquery40-LetBinding">LetBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-WindowClause">
                  <lhs>WindowClause</lhs>
                  <rhs>"for"  (<nt def="prod-xquery40-TumblingWindowClause">TumblingWindowClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SlidingWindowClause">SlidingWindowClause<!--$idref_lang_part = xquery40- --></nt>)</rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-IntermediateClause">
                  <lhs>IntermediateClause</lhs>
                  <rhs>
                     <nt def="prod-xquery40-InitialClause">InitialClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-WhereClause">WhereClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-WhileClause">WhileClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-GroupByClause">GroupByClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-OrderByClause">OrderByClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CountClause">CountClause<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-WhereClause">
                  <lhs>WhereClause</lhs>
                  <rhs>"where"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-WhileClause">
                  <lhs>WhileClause</lhs>
                  <rhs>"while"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-GroupByClause">
                  <lhs>GroupByClause</lhs>
                  <rhs>"group"  "by"  (<nt def="prod-xquery40-GroupingSpec">GroupingSpec<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-OrderByClause">
                  <lhs>OrderByClause</lhs>
                  <rhs>"stable"?  "order"  "by"  (<nt def="prod-xquery40-OrderSpec">OrderSpec<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-CountClause">
                  <lhs>CountClause</lhs>
                  <rhs>"count"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FLWORExpr-ReturnClause">
                  <lhs>ReturnClause</lhs>
                  <rhs>"return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p role="xquery">The semantics of FLWOR expressions are based on a concept called a <term>tuple stream</term>. <termdef id="id-tuple-stream-foobar" term="tuple stream">A <term>tuple stream</term> is an ordered sequence of zero or more <term>tuples</term>.</termdef>
               <termdef term="tuple" id="id-tuple-foobar">A <term>tuple</term> is a set of zero or more named variables, each of which is bound to a value that is an <termref def="dt-data-model-instance">XDM instance</termref>.</termdef> Each tuple stream is homogeneous in the sense that all its  tuples contain variables with the same names and the same <termref def="dt-static-type">static types</termref>. The following example illustrates a tuple stream consisting of four tuples, each containing three variables named <code nobreak="false">$x</code>, <code nobreak="false">$y</code>, and <code nobreak="false">$z</code>:</p>
            <eg role="xquery" xml:space="preserve">($x = 1003, $y = "Fred", $z = &lt;age&gt;21&lt;/age&gt;)
($x = 1017, $y = "Mary", $z = &lt;age&gt;35&lt;/age&gt;)
($x = 1020, $y = "Bill", $z = &lt;age&gt;18&lt;/age&gt;)
($x = 1024, $y = "John", $z = &lt;age&gt;29&lt;/age&gt;)</eg>
            <note role="xquery">
               <p>In this section, tuple streams are represented as shown in the above example. Each tuple is on a separate line and is enclosed in parentheses, and the variable bindings inside each tuple are separated by commas. This notation does not represent XQuery syntax, but is simply a representation of a tuple stream for the purpose of defining the semantics of  FLWOR expressions.</p>
            </note>
            <p role="xquery">Tuples and tuple streams are not part of the <termref def="dt-datamodel">data model</termref>. They exist only as conceptual intermediate results during the processing of a FLWOR expression.</p>
            <p role="xquery">Conceptually, the first clause generates a tuple stream. Each clause between the first clause and the return clause takes the tuple stream generated by the previous clause as input and generates a (possibly different) tuple stream as output. The return clause takes a tuple stream as input and, for each tuple in this tuple stream, generates an <termref def="dt-data-model-instance">XDM instance</termref>; the final result of the FLWOR expression is the ordered concatenation of these <termref def="dt-data-model-instance">XDM instances</termref>.</p>
            <p role="xquery">The initial clause in a FLWOR expression may be a <code nobreak="false">for</code>, <code nobreak="false">let</code>, or <code nobreak="false">window</code> clause. 
Intermediate clauses may be <code nobreak="false">for</code>, <code nobreak="false">let</code>, <code nobreak="false">window</code>, <code nobreak="false">count</code>, <code nobreak="false">where</code>, <code nobreak="false">group by</code>, or <code nobreak="false">order by</code> clauses. These intermediate clauses may be repeated as many times as desired, in any order. The final clause of the FLWOR expression must be a <code nobreak="false">return</code> clause. The semantics of the various clauses are described in the following sections.</p>
            <div3 id="id-binding-rules" role="xquery">
               <head>Variable Bindings</head>
               <p>The following clauses in FLWOR expressions bind values to variables: 
<code nobreak="false">for</code>, <code nobreak="false">let</code>, <code nobreak="false">window</code>, <code nobreak="false">count</code>, and <code nobreak="false">group by</code>. 
The binding of variables for <code nobreak="false">for</code>, <code nobreak="false">let</code>, and <code nobreak="false">count</code> is governed by the following rules
(the binding of variables in <code nobreak="false">group by</code> is discussed in <specref ref="id-group-by"/>,
the binding of variables in <code nobreak="false">window</code> clauses is discussed in <specref ref="id-windows"/>):</p>
               <olist>
                  <item>
                     <p>The scope of a bound variable includes all subexpressions of the containing FLWOR that appear after the variable binding. The scope does not include the expression to which the variable is bound. The following code fragment, containing two <code nobreak="false">let</code> clauses, illustrates how variable bindings may reference variables that were bound in earlier clauses, or in earlier bindings in the same clause:</p>
                     <eg xml:space="preserve">let $x := 47, $y := f($x)
let $z := g($x, $y)</eg>
                  </item>
                  <item>
                     <p>A given variable name may be bound more than once in a FLWOR expression, 
                     or even within one clause of a FLWOR expression. In such a case, each new 
                     binding occludes the previous one, which becomes inaccessible in the 
                     remainder of the FLWOR expression.</p>
                     <p>For example, it is valid to write:</p>
                     <eg xml:space="preserve">let $x := 0, $x := $x*2, $x := $x + 1</eg>
                     <p>This binds three separate variables, each of which happens to have the
                  same name. It should not be construed as binding a series of different values
                  to the same variable.</p>
                  </item>
                  <item>
                     <p>
                        <termdef term="type declaration" id="dt-type-declaration">A variable binding may be accompanied by a <term>type declaration</term>, which consists of the 
                        keyword <code nobreak="false">as</code> followed by the static type of the variable, declared using the syntax in  <specref ref="id-sequencetype-syntax"/>.</termdef> The type declaration defines a required type for the
                        value. At run-time, the supplied value for the variable is converted to the required type
                        by applying the <termref def="dt-coercion-rules"/>. If conversion is not possible,                     
                        a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>. For example, the following <code nobreak="false">let</code> clause raises a <termref def="dt-type-error">type error</termref> because the variable <code nobreak="false">$salary</code> has a type declaration that is not satisfied by the value that is bound to it:</p>
                     <eg xml:space="preserve">let $salary as xs:decimal := "cat"</eg>
                     <p diff="add" at="2022-11-17">The following <code nobreak="false">let</code> clause, however, succeeds, because the <termref def="dt-coercion-rules"/>
                  allow an <code nobreak="false">xs:decimal</code> to be supplied where an <code nobreak="false">xs:double</code> is required:</p>
                     <eg xml:space="preserve">let $temperature as xs:double := 32.5</eg>
                     <p>In applying the <termref def="dt-coercion-rules"/>, <termref def="dt-xpath-compat-mode"/> does not apply.</p>
                  </item>
                  <item diff="add" at="A">
                     <p>
                        <termdef id="dt-binding-collection" term="binding collection">In a <code nobreak="false">for</code> clause, when an expression is 
                        preceded by the keyword <code nobreak="false">in</code>, the value of that expression is 
                        called a <term>binding collection</term>.</termdef> The collection may be either
                     a sequence, an array, or a map. The <code nobreak="false">for</code>  
                     clause iterates over its binding collection, producing multiple bindings for one or more variables. 
                     Details on how binding collections are used in <code nobreak="false">for</code> clauses 
                     are described in the following sections.</p>
                  </item>
                  <item diff="chg" at="A">
                     <p>
                        <termdef id="dt-binding-sequence" term="binding sequence">In a <code nobreak="false">window</code> clause, when an expression is 
                        preceded by the keyword <code nobreak="false">in</code>, the value of that expression is 
                        called a <term>binding sequence</term>.</termdef> The <code nobreak="false">window</code> 
                     clause iterates over its binding sequence, producing multiple bindings for one or more variables. 
                     Details on how binding sequences are used in <code nobreak="false">for</code> and <code nobreak="false">window</code> clauses 
                     are described in the following sections.</p>
                  </item>
               </olist>
            </div3>
            <div3 id="id-xquery-for-clause" role="xquery">
               <head>For Clause</head>
               <changes>
                  <change issue="49" PR="344" date="2023-02-10">A <code nobreak="false">for member</code> clause is added to 
                  FLWOR expressions to allow iteration over an array.
               </change>
                  <change issue="31" PR="1249" date="2024-06-01">A <code nobreak="false">for key/value</code> clause is added to 
                  FLWOR expressions to allow iteration over a map.
               </change>
                  <change issue="189" PR="820" date="2023-11-08">
                  The value bound to a variable in a <code nobreak="false">for</code> clause is now converted
                     to the declared type by applying the coercion rules.
               </change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-ForClause">
                     <lhs>ForClause</lhs>
                     <rhs>"for"  (<nt def="prod-xquery40-ForBinding">ForBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-ForBinding">
                     <lhs>ForBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ForItemBinding">ForItemBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ForMemberBinding">ForMemberBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ForEntryBinding">ForEntryBinding<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-ForItemBinding">
                     <lhs>ForItemBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-AllowingEmpty">AllowingEmpty<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-VarNameAndType">
                     <lhs>VarNameAndType</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-TypeDeclaration">
                     <lhs>TypeDeclaration</lhs>
                     <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-AllowingEmpty">
                     <lhs>AllowingEmpty</lhs>
                     <rhs>"allowing"  "empty"</rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-PositionalVar">
                     <lhs>PositionalVar</lhs>
                     <rhs>"at"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-VarName">
                     <lhs>VarName</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-ForMemberBinding">
                     <lhs>ForMemberBinding</lhs>
                     <rhs>"member"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-ForEntryBinding">
                     <lhs>ForEntryBinding</lhs>
                     <rhs>((<nt def="prod-xquery40-ForEntryKeyBinding">ForEntryKeyBinding<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-ForEntryValueBinding">ForEntryValueBinding<!--$idref_lang_part = xquery40- --></nt>?)  |  <nt def="prod-xquery40-ForEntryValueBinding">ForEntryValueBinding<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-ForEntryKeyBinding">
                     <lhs>ForEntryKeyBinding</lhs>
                     <rhs>"key"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ForClause-ForEntryValueBinding">
                     <lhs>ForEntryValueBinding</lhs>
                     <rhs>"value"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>A <code nobreak="false">for</code> clause is used for iteration. Each variable in a <code nobreak="false">for</code> clause iterates over a 
               sequence, an array, or a map.</p>
               <p>The expression following the keyword <code nobreak="false">in</code> is evaluated; we refer to the 
               resulting sequence, array, or map generically as the <termref def="dt-binding-collection"/>, and to
               its items, members, or entries as the <code nobreak="false">components</code> of the collection.</p>
               <ulist>
                  <item>
                     <p>When a <nt def="prod-xquery40-ForItemBinding">ForItemBinding<!--$spec = xquery40--></nt> is used (that is, when none of the
                  keywords <code nobreak="false">member</code>, <code nobreak="false">key</code>, or <code nobreak="false">value</code> is used), 
                  the range variable is bound in turn to each item in the <termref def="dt-binding-collection"/>,
                  which is treated as a sequence of items.</p>
                  </item>
                  <item>
                     <p>When a <nt def="prod-xquery40-ForItemBinding">ForMemberBinding<!--$spec = xquery40--></nt> is used (that is, when the
               keyword <code nobreak="false">member</code> is used), 
               the range variable is bound in turn to each member of the array.</p>
                     <p>In this case the corresponding <code nobreak="false">ExprSingle</code>
                  must evaluate to a single array, otherwise a type error is raised <errorref class="TY" code="0141"/>. However, the coercion rules also allow a JNode
                  whose <term>·jvalue·</term> is an array to be supplied.</p>
                  </item>
                  <item>
                     <p>When a <nt def="prod-xquery40-ForItemBinding">ForEntryBinding<!--$spec = xquery40--></nt> is used (that is, when either
                  or both of the keywords <code nobreak="false">key</code> and <code nobreak="false">value</code> are used), 
                  the <code nobreak="false">key</code> range variable (if present) is bound in turn to each key in the map 
                  (in <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>), and the <code nobreak="false">value</code>
                  range variable (if present) is bound to the corresponding value.</p>
                     <p>In this case the corresponding <code nobreak="false">ExprSingle</code>
                  must evaluate to a single map, otherwise a type error is raised <errorref class="TY" code="0141"/>. However, the coercion rules also allow a JNode
                  whose <term>·jvalue·</term> is a map to be supplied.</p>
                     <p>If both the <code nobreak="false">key</code> and <code nobreak="false">value</code> variables are declared,
               their <termref def="dt-expanded-qname">expanded
			        QNames</termref> must be distinct <errorref class="ST" code="0089"/>.</p>
                  </item>
               </ulist>
               <p>If a <code nobreak="false">for</code> clause contains multiple bindings separated by commas 
               it is semantically equivalent to multiple <code nobreak="false">for</code> clauses, 
               each containing one of the bindings in the original <code nobreak="false">for</code> clause.</p>
               <p>Example:</p>
               <ulist>
                  <item>
                     <p>The clause</p>
                     <eg xml:space="preserve">for $x in $expr1, $y in $expr2</eg>
                     <p>is semantically equivalent to:</p>
                     <eg xml:space="preserve">for $x in $expr1
for $y in $expr2</eg>
                  </item>
                  <item>
                     <p>The clause</p>
                     <eg xml:space="preserve">for member $x in $expr1, member $y in $expr2</eg>
                     <p>is semantically equivalent to:</p>
                     <eg xml:space="preserve">for member $x in $expr1
for member $y in $expr2</eg>
                  </item>
               </ulist>
               <p>In the remainder of this section, we define the semantics of a <code nobreak="false">for</code> clause containing 
               a single variable and an associated expression 
               (following the keyword <code nobreak="false">in</code>) whose value is the <termref def="dt-binding-collection">binding collection</termref> for that variable.</p>
               <p>If a single-variable <code nobreak="false">for</code> clause is the initial clause in a FLWOR expression, it iterates over its <termref def="dt-binding-collection">binding collection</termref>, binding the variable(s) to each component in turn. 
               The resulting sequence of variable bindings becomes the initial tuple stream that serves as input to the next clause 
               of the FLWOR expression. The order of tuples in the tuple stream preserves the order of the <termref def="dt-binding-collection">binding collection</termref>.</p>
               <p>If the <termref def="dt-binding-sequence">binding collection</termref> is empty, the output tuple stream depends on whether <code nobreak="false">allowing empty</code> is specified. 
               If <code nobreak="false">allowing empty</code> is specified, the output tuple stream consists of one tuple in which the variable is bound to the empty sequence.
               This option is not available when the keywords <code nobreak="false">member</code>, <code nobreak="false">key</code>, or <code nobreak="false">value</code>
               are used.
               If <code nobreak="false">allowing empty</code> is not specified, the output tuple stream consists of zero tuples.</p>
               <p>The following  examples illustrates tuple streams that are generated by initial <code nobreak="false">for</code> clauses:</p>
               <ulist>
                  <item>
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for $x in (100, 200, 300)</eg>
                     <p>or (equivalently):</p>
                     <eg xml:space="preserve">for $x allowing empty in (100, 200, 300)</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = 100)
($x = 200)
($x = 300)</eg>
                  </item>
                  <item>
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for $x in ()</eg>
                     <p>Output tuple stream contains no tuples.</p>
                  </item>
                  <item>
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for $x allowing empty in ()</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = ())</eg>
                  </item>
                  <item diff="add" at="A">
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for member $x in [ 1, 2, (5 to 10) ] </eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = (1))
($x = (2))
($x = (5, 6, 7, 8, 9, 10)</eg>
                  </item>
                  <item diff="add" at="A">
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for member $x in []</eg>
                     <p>Output tuple stream contains no tuples.</p>
                  </item>
                  <item>
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for key $k value $v in { 'x': 1, 'y': 2 }</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($k = 'x', $v = 1)
($k = 'y', $v = 2)</eg>
                  </item>
               </ulist>
               <p>
                  <termdef term="positional variable" id="dt-positional-variable">A <term>positional variable</term> 
                  is a variable that is preceded by the keyword <code nobreak="false">at</code>.</termdef> A positional variable 
               may be associated with the range variable(s) that are bound in a <code nobreak="false">for</code> clause. In this case, as 
               the main range variable(s) iterate over the components of its <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref>, 
               the positional variable iterates over the integers that represent the ordinal numbers of these component in the 
               <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref>, starting with one. Each tuple in the output 
               tuple stream contains bindings for both the main variable and the positional variable. If the 
               <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> is empty and <code nobreak="false">allowing empty</code> is 
               specified, the positional variable in the output tuple is bound to the integer zero. Positional variables  
               have the implied type <code nobreak="false">xs:integer</code>.</p>
               <p>The <termref def="dt-expanded-qname">expanded
			        QName</termref> of a positional variable must be distinct from the <termref def="dt-expanded-qname">expanded QName</termref> of the main variable with which it is associated <errorref class="ST" code="0089"/>.</p>
               <p>The following  examples illustrate how a positional variable would have affected the results of the previous examples that generated tuples:</p>
               <ulist>
                  <item>
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for $x at $i in (100, 200, 300)</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = 100, $i = 1)
($x = 200, $i = 2)
($x = 300, $i = 3)</eg>
                  </item>
                  <item diff="add" at="A">
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for $x at $i in [1 to 3, 11 to 13, 21 to 23</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = (1, 2, 3), $i = 1)
($x = (11, 12, 13), $i = 2)
($x = (21, 22, 23), $i = 3)</eg>
                  </item>
                  <item>
                     <p>Initial clause:</p>
                     <eg xml:space="preserve">for $x allowing empty at $i in ()</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = (), $i = 0)</eg>
                  </item>
               </ulist>
               <p>If a single-variable <code nobreak="false">for</code> clause is an intermediate clause in a FLWOR expression, its <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> is evaluated for each input tuple, given the bindings in that input tuple. Each input tuple generates 
                  zero or more tuples in the output tuple stream. Each of these output tuples consists of  the original variable bindings of the 
                  input tuple plus a binding of the new variable to one of the items in its <termref def="dt-binding-collection" diff="chg" at="A">binding collecction</termref>.</p>
               <note>
                  <p>Although the <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> is conceptually evaluated independently for each input tuple, 
                  an optimized implementation may sometimes be able to avoid re-evaluating the <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> if it can show that the variables that the <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> depends on have the same values as in a previous evaluation.</p>
               </note>
               <p>For a given input tuple, if the <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> for the new variable in the <code nobreak="false">for</code> clause <phrase diff="add" at="A">is empty 
               (that is, it is the empty sequence or an <xtermref spec="DM40" ref="dt-empty-array"/> depending on whether <code nobreak="false">member</code> is specified)</phrase>,
               and if <code nobreak="false">allowing empty</code> is not specified, the input tuple generates zero output tuples 
               (it is not represented in the output tuple stream.)</p>
               <p>The <code nobreak="false">allowing empty</code> option is available only when processing sequences, not when processing arrays or maps.
               The effect is that if the binding collection is the empty sequence, the input tuple generates one output tuple, 
               with the original variable bindings plus a binding of the new variable to the empty sequence.</p>
               <note diff="add" at="2023-10-16">
                  <p>If a type declaration is present and <code nobreak="false">allowing empty</code> is specified, the type declaration
            should include an occurrence indicator of <code nobreak="false">"?"</code> to indicate that the variable may be bound to an
            empty sequence.</p>
               </note>
               <p>If the new variable introduced by a <code nobreak="false">for</code> clause has an associated <termref def="dt-positional-variable">positional variable</termref>, the output tuples generated by the <code nobreak="false">for</code> clause  also contain bindings for the <termref def="dt-positional-variable">positional variable</termref>. In this case, as the new variable is bound to each item in its <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref>, the <termref def="dt-positional-variable">positional variable</termref> is bound to the ordinal position of that item within the <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref>, starting with one. Note that, since the <termref def="dt-positional-variable">positional variable</termref> represents a position within a <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref>, the output tuples corresponding to each input tuple are independently numbered, starting with one. For a given input tuple, if the <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> is empty and <code nobreak="false">allowing empty</code> is specified, the <termref def="dt-positional-variable">positional variable</termref> in the output tuple is bound to the integer zero.</p>
               <p>The tuples in the output tuple stream are ordered primarily by the order of the 
               input tuples from which they are derived, and secondarily by the order of the <termref def="dt-binding-sequence">binding sequence</termref> for the new variable; otherwise the order of the output tuple stream is <termref def="dt-implementation-dependent">implementation-dependent</termref>.</p>
               <p>The following examples illustrates the effects of  intermediate <code nobreak="false">for</code> clauses:</p>
               <ulist>
                  <item>
                     <p>Input tuple stream:</p>
                     <eg xml:space="preserve">($x = 1)
($x = 2)
($x = 3)
($x = 4)</eg>
                     <p>Intermediate <code nobreak="false">for</code> clause:</p>
                     <eg xml:space="preserve">for $y in ($x to 3)</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = 1, $y = 1)
($x = 1, $y = 2)
($x = 1, $y = 3)
($x = 2, $y = 2)
($x = 2, $y = 3)
($x = 3, $y = 3)
</eg>
                     <note>
                        <p>In this example, there is no output tuple that corresponds to the input tuple <code nobreak="false">($x = 4)</code> because, when the <code nobreak="false">for</code> clause is evaluated with the bindings in this input tuple, the resulting <termref def="dt-binding-collection" diff="chg" at="A">binding collection</termref> for <code nobreak="false">$y</code> is empty.</p>
                     </note>
                  </item>
                  <item>
                     <p>This  example shows how the previous example would have been affected by a <termref def="dt-positional-variable">positional variable</termref> (assuming the same input tuple stream):</p>
                     <eg xml:space="preserve">for $y at $j in ($x to 3)</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = 1, $y = 1, $j = 1)
($x = 1, $y = 2, $j = 2)
($x = 1, $y = 3, $j = 3)
($x = 2, $y = 2, $j = 1)
($x = 2, $y = 3, $j = 2)
($x = 3, $y = 3, $j = 1)
</eg>
                  </item>
                  <item>
                     <p>This example shows how the previous example would have been affected by <code nobreak="false">allowing empty</code>. Note that <code nobreak="false">allowing empty</code> causes the input tuple <code nobreak="false">($x = 4)</code> to be represented in the output tuple stream, even though the <termref def="dt-binding-sequence">binding sequence</termref> for <code nobreak="false">$y</code> contains no items for this input tuple.
                        This example illustrates that <code nobreak="false">allowing empty</code> in a <code nobreak="false">for</code> clause
                        serves a purpose similar to that of an “outer join” in a relational database query.
                        (Assume the same input tuple stream as in the previous example.)</p>
                     <eg xml:space="preserve">for $y allowing empty at $j in ($x to 3)</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = 1, $y = 1, $j = 1)
($x = 1, $y = 2, $j = 2)
($x = 1, $y = 3, $j = 3)
($x = 2, $y = 2, $j = 1)
($x = 2, $y = 3, $j = 2)
($x = 3, $y = 3, $j = 1)
($x = 4, $y = (), $j = 0)
</eg>
                  </item>
                  <item diff="add" at="A">
                     <p>This example illustrates processing of arrays:</p>
                     <p>Input tuple stream:</p>
                     <eg xml:space="preserve">($x = 1)
($x = 2)
($x = 3)</eg>
                     <p>Intermediate <code nobreak="false">for</code> clause:</p>
                     <eg xml:space="preserve">for member $y in [[$x+1, $x+2], [[$x+3, $x+4]] </eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = 1, $y = [ 2, 3 ])
($x = 1, $y = [ 4, 5 ])
($x = 2, $y = [ 3, 4 ])
($x = 2, $y = [ 5, 6 ])
($x = 3, $y = [ 4, 5 ])
($x = 3, $y = [ 6, 7 ])
</eg>
                  </item>
                  <item>
                     <p>This example shows how a <code nobreak="false">for</code> clause that binds two variables is semantically equivalent to two <code nobreak="false">for</code> clauses that bind one variable each. We assume that this <code nobreak="false">for</code> clause occurs at the beginning of a FLWOR expression. It is equivalent to an initial single-variable <code nobreak="false">for</code> clause that provides an input tuple stream to an intermediate single-variable <code nobreak="false">for</code> clause.</p>
                     <eg xml:space="preserve">for $x in (1, 2, 3, 4), $y in ($x to 3)</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($x = 1, $y = 1)
($x = 1, $y = 2)
($x = 1, $y = 3)
($x = 2, $y = 2)
($x = 2, $y = 3)
($x = 3, $y = 3)
</eg>
                  </item>
               </ulist>
               <p>A <code nobreak="false">for</code> clause may contain one or more <termref def="dt-type-declaration">type declarations</termref>, identified by the keyword <code nobreak="false">as</code>. The semantics of <termref def="dt-type-declaration">type declarations</termref> are defined in <specref ref="id-binding-rules"/>.</p>
            </div3>
            <div3 id="id-xquery-let-clause" role="xquery">
               <head>Let Clause</head>
               <changes>
                  <change issue="189" PR="254" date="2022-11-29">
                  The value bound to a variable in a <code nobreak="false">let</code> clause is now converted
               to the declared type by applying the coercion rules.
               </change>
                  <change issue="37" PR="2055" date="2025-06-17">
               Sequences, arrays, and maps can be destructured in a <code nobreak="false">let</code> 
               clause to extract their components into multiple variables. 
            </change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-LetClause">
                     <lhs>LetClause</lhs>
                     <rhs>"let"  (<nt def="prod-xquery40-LetBinding">LetBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-LetBinding">
                     <lhs>LetBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-LetValueBinding">LetValueBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetSequenceBinding">LetSequenceBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetArrayBinding">LetArrayBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetMapBinding">LetMapBinding<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-LetValueBinding">
                     <lhs>LetValueBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-VarNameAndType">
                     <lhs>VarNameAndType</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-TypeDeclaration">
                     <lhs>TypeDeclaration</lhs>
                     <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-LetSequenceBinding">
                     <lhs>LetSequenceBinding</lhs>
                     <rhs>"$"  "("  (<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-LetArrayBinding">
                     <lhs>LetArrayBinding</lhs>
                     <rhs>"$"  "["  (<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ++ ",")  "]"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-LetClause-LetMapBinding">
                     <lhs>LetMapBinding</lhs>
                     <rhs>"$"  "{"  (<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ++ ",")  "}"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>The purpose of a <code nobreak="false">let</code> clause is to bind values to one or more variables. 
               Each variable is bound to the result of evaluating an expression.</p>
               <p>If a <code nobreak="false">let</code> clause declares multiple variables separated by commas, 
               it is semantically equivalent to multiple <code nobreak="false">let</code> clauses, 
               each containing a single variable. For example, the clause</p>
               <eg xml:space="preserve">let $x := $expr1, $y := $expr2</eg>
               <p>is semantically equivalent to the following sequence of clauses:</p>
               <eg xml:space="preserve">let $x := $expr1
let $y := $expr2</eg>
               <p>After performing this expansion, the effect of a <code nobreak="false">let</code> clause is as follows:</p>
               <olist>
                  <item>
                     <p>If the let expression uses multiple variables, it is first expanded to a
set of nested let expressions, each of which uses only one variable. 
Specifically, any separating comma is replaced by <code nobreak="false">let</code>.</p>
                     <example>
                        <head>Example:</head>
                        <p>The expression:</p>
                        <eg xml:space="preserve">let $x := 4, $y := 3 return $x + $y</eg>
                        <p>is expanded to:</p>
                        <eg xml:space="preserve">let $x := 4 let $y := 3 return $x + $y</eg>
                     </example>
                  </item>
                  <item>
                     <p>In a <nt def="prod-xquery40-LetValueBinding">LetValueBinding<!--$spec = xquery40--></nt>
                  such as <code nobreak="false">let $<var>V</var> as <var>T</var> := <var>EXPR</var>
                        </code>:</p>
                     <olist>
                        <item>
                           <p>The variable <var>V</var> is declared as a <term>range variable</term>.</p>
                        </item>
                        <item>
                           <p>The sequence type <var>T</var> is called the <term>declared type</term>.
                     If there is no declared type, then <code nobreak="false">item()*</code> is assumed.</p>
                        </item>
                        <item>
                           <p>The expression <var>EXPR</var> is evaluated, and its value is converted
                     to the declared type by applying the <termref def="dt-coercion-rules"/>.
                     The resulting value forms the <term>binding sequence</term> for the range variable.</p>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>In a <nt def="prod-xquery40-LetSequenceBinding">LetSequenceBinding<!--$spec = xquery40--></nt>
                  such as <code nobreak="false">let $( $<var>A1</var> as <var>T1</var>, $<var>A2</var> as <var>T2</var>, ...
                     , $<var>A/n</var> as <var>T/n</var> ) as <var>ST</var> := <var>EXPR</var>
                        </code>:</p>
                     <olist>
                        <item>
                           <p>The sequence type <var>ST</var> is called the <term>declared sequence type</term>.
                     If there is no declared sequence type, then <code nobreak="false">item()*</code> is assumed.</p>
                        </item>
                        <item>
                           <p>The expression <var>EXPR</var> is evaluated, and its value is converted
                     to the declared sequence type <var>ST</var> by applying the <termref def="dt-coercion-rules"/>.
                     Call the resulting (coerced) value <var>V</var>.</p>
                        </item>
                        <item>
                           <p>Each variable <var>A/i</var> (for <var>i</var> in 1 to <var>n</var>-1)
                     is effectively replaced by a <nt def="prod-xquery40-LetValueBinding">LetValueBinding<!--$spec = xquery40--></nt>
                        of the form <code nobreak="false">let <var>A/i</var> as <var>T/i</var> := items-at(<var>V</var>, <var>i</var>)</code>.
                     That is, a <term>range variable</term> named <var>A/i</var> is declared, whose <term>binding sequence</term>
                     is the item <var>V[ i ]</var>, after coercion to the type <var>T/i</var> if specified.
                     If <var>T/i</var> is absent, no further coercion takes place (the default is effectively
                     <code nobreak="false">item()?</code>).</p>
                        </item>
                        <item>
                           <p>The last variable <var>A/n</var> 
                     is effectively replaced by a <nt def="prod-xquery40-LetValueBinding">LetValueBinding<!--$spec = xquery40--></nt>
                        of the form <code nobreak="false">let <var>A/n</var> as <var>T/n</var> := subsequence(<var>V</var>, <var>n</var>)</code>.
                        That is, the last variable is bound to the rest of the binding sequence (or to the empty sequence
                        if the binding sequence has fewer items than the number of variables).
                     </p>
                        </item>
                     </olist>
                     <note>
                        <p>For any variable <var>A/i</var>, including the last, 
                           if <var>i</var> exceeds the length of the sequence <var>V</var>, then
                        <var>A/i</var> is bound to the empty sequence. This will cause a type error if
                        type <var>T/i</var> does not permit the empty sequence.</p>
                     </note>
                     <note>
                        <p>It is permissible to bind several variables with the same name;
                        all but the last are occluded. A useful convention is therefore to bind
                        items in the sequence that are of no interest to the variable <code nobreak="false">$_</code>:
                        for example <code nobreak="false">let $( $_, $_, $x ) := <var>EXPR</var>
                           </code> effectively
                        binds <code nobreak="false">$x</code> to the subsequence starting at the third item, while causing the first two
                        items to be ignored.</p>
                     </note>
                     <example>
                        <head>Example:</head>
                        <p>The expression:</p>
                        <eg xml:space="preserve">let $( $a, $b as xs:integer, $local:c ) := (2, 4, 6)
return $a + $b + $local:c</eg>
                        <p>is expanded to:</p>
                        <eg xml:space="preserve">let $temp := (2, 4, 6)
let $a := fn:items-at($temp, 1)
let $b as xs:integer := fn:items-at($temp, 2)
let $local:c := fn:subsequence($temp, 3)
return $a + $b + $local:c</eg>
                        <p>where <code nobreak="false">$temp</code> is some variable name that is otherwise unused.</p>
                     </example>
                     <example>
                        <head>Example:</head>
                        <p>Consider the element <var>$E</var> := <code nobreak="false">&lt;e A="p q r" B="x y z"/&gt;</code>.</p>
                        <p>Then consider the expression:</p>
                        <eg xml:space="preserve">let $( $a, $b ) := $E!(@A, @B)</eg>
                        <p>Here the binding sequence is a sequence of two attribute nodes, so
                        <code nobreak="false">$a</code> is bound to the attribute <code nobreak="false">@A</code>, and <code nobreak="false">$b</code>
                        is bound to the attribute node <code nobreak="false">@B</code>.</p>
                        <p>If the operator <code nobreak="false">"!"</code> were replaced by <code nobreak="false">"/"</code>, or if
                        <code nobreak="false">","</code> were replaced by <code nobreak="false">"|"</code>, then the binding sequence
                        would be sorted into document order, and since the order of attributes is
                        not defined, this would make it unpredictable which variable is bound
                        to which attribute node.</p>
                        <p>Now consider what happens when a declared sequence type is added:</p>
                        <eg xml:space="preserve">let $( $a, $b ) as xs:string* := $E!(@A, @B)</eg>
                        <p>The sequence of two attribute nodes is now atomized to form a sequence of strings.
                        The first string in this sequence is bound to <code nobreak="false">$a</code>, and the remainder
                        of the sequence is bound to <code nobreak="false">$b</code>. If the element <code nobreak="false">$E</code> is untyped,
                        this will result in <code nobreak="false">$a</code> being bound to the <code nobreak="false">xs:untypedAtomic</code>
                        value <code nobreak="false">"p q r"</code>, while <code nobreak="false">$b</code> is bound to the <code nobreak="false">xs:untypedAtomic</code>
                        value <code nobreak="false">"x y z"</code>.</p>
                        <p>However, suppose that the element <code nobreak="false">$E</code> has been validated against a schema
                        that defines both attributes <code nobreak="false">@A</code> and <code nobreak="false">@B</code> as list types with
                        item type <code nobreak="false">xs:string</code>. In this case, the atomized value of <code nobreak="false">$E</code>
                        will be a sequence of six strings. The variable <code nobreak="false">$a</code> is bound to the first
                        of these strings (that is, <code nobreak="false">"p"</code>), while <code nobreak="false">$b</code> is bound to a
                        sequence containing the remaining five strings (that is, <code nobreak="false">("q", "r", "x", "y", "z")</code>).</p>
                        <p>By contrast, if the expression is written as:</p>
                        <eg xml:space="preserve">let $( $a as xs:string*, $b as xs:string* ) := $E!(@A, @B)</eg>
                        <p>then <code nobreak="false">$a</code> is bound to the result of atomizing the first attribute
                     (the <code nobreak="false">untypedAtomic</code> value <code nobreak="false">"p q r"</code> in the untyped case, or
                     the sequence of three strings <code nobreak="false">("p", "q", "r")</code> in the schema-validated case),
                     while <code nobreak="false">$b</code> is similarly bound to the result of atomizing the second attribute.</p>
                     </example>
                     <example>
                        <head>Example:</head>
                        <p>Consider transforming the string <code nobreak="false">"Nf3 Nf6 c4 g6 Nc3 Bg7 d4 O-O Bf4 d5"</code>
                     (notation for the start of a chess game) to the form 
                     <code nobreak="false">(["Nf3", "Nf6",] ["c4", "g6"], [ "Nc3", "Bg7"], [ "d4", "O-O"], ["Bf4", "d5"])</code>.
                     This can be achieved as follows:</p>
                        <eg xml:space="preserve">declare function local:grouped-moves($moves) {
   if (exists($moves)) {
     let $($m1, $m2, $rest) := $moves
     return [$m1, $m2], local:grouped-moves($rest)
  }
};
local:grouped-moves(tokenize("Nf3 Nf6 c4 g6 Nc3 Bg7 d4 O-O Bf4 d5"))</eg>
                     </example>
                  </item>
                  <item>
                     <p>In a <nt def="prod-xquery40-LetArrayBinding">LetArrayBinding<!--$spec = xquery40--></nt>
                  such as <code nobreak="false">let $[ $<var>A1</var> as <var>T1</var>, $<var>A2</var> as <var>T2</var>, ...
                     , $<var>A/n</var> as <var>T/n</var> ] as <var>AT</var> := <var>EXPR</var>
                        </code>:</p>
                     <olist>
                        <item>
                           <p>The sequence type <var>AT</var> is called the <term>declared array type</term>.
                     If there is no declared array type, then <code nobreak="false">array(*)</code> is assumed.</p>
                        </item>
                        <item>
                           <p>The expression <var>EXPR</var> is evaluated, and its value is converted
                     to the declared array type <var>AT</var> by applying the <termref def="dt-coercion-rules"/>.
                     A type error <errorref class="TY" code="0004"/> is raised if the result is not
                        a <termref def="dt-singleton"/> array.
                     Call the resulting (coerced) value <var>V</var>.</p>
                        </item>
                        <item>
                           <p>Each variable <var>A/i</var> (for <var>i</var> in 1 to <var>n</var>)
                     is effectively replaced by a <nt def="prod-xquery40-LetValueBinding">LetValueBinding<!--$spec = xquery40--></nt>
                        of the form <code nobreak="false">let <var>A/i</var> as <var>T/i</var> := array:get(<var>V</var>, <var>i</var>)</code>.
                     That is, a <term>range variable</term> named <var>A/i</var> is declared, whose <term>binding sequence</term>
                     is the array member <var>V ? i</var>, after coercion to the type <var>T/i</var> if specified.
                     If <var>T/i</var> is absent, no further coercion takes place (the default is effectively
                     <code nobreak="false">item()*</code>).</p>
                           <note>
                              <p>If <var>i</var> exceeds the length of the array <var>V</var>, then
                        an error <xerrorref spec="FO" class="AR" code="0001"/> is raised.</p>
                           </note>
                           <note>
                              <p>It is permissible to bind several variables with the same name;
                        all but the last are occluded. A useful convention is therefore to bind
                        items in the sequence that are of no interest to the variable <code nobreak="false">$_</code>:
                        for example <code nobreak="false">let $( $_, $_, $x ) := <var>EXPR</var>
                                 </code> effectively
                        binds <code nobreak="false">$x</code> to the third item in the sequence and causes the first two
                        items to be ignored.</p>
                           </note>
                           <example>
                              <head>Example:</head>
                              <p>The expression:</p>
                              <eg xml:space="preserve">let $[ $a, $b as xs:integer, $local:c ] := [ 2, 4, 6 ]
return $a + $b + $local:c</eg>
                              <p>is expanded to:</p>
                              <eg xml:space="preserve">let $temp := [ 2, 4, 6 ]
let $a := array:get($temp, 1, ())
let $b as xs:integer := array:get($temp, 2)
let $local:c := array:get($temp, 3, ())
return $a + $b + $local:c</eg>
                              <p>where <code nobreak="false">$temp</code> is some variable name that is otherwise unused.</p>
                           </example>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>In a <nt def="prod-xquery40-LetMapBinding">LetMapBinding<!--$spec = xquery40--></nt>
                  such as <code nobreak="false">let ${ $<var>A1</var> as <var>T1</var>, $<var>A2</var> as <var>T2</var>, ...
                     , $<var>A/n</var> as <var>T/n</var> } as <var>MT</var> := <var>EXPR</var>
                        </code>:</p>
                     <olist>
                        <item>
                           <p>The sequence type <var>MT</var> is called the <term>declared map type</term>.
                     If there is no declared map type, then <code nobreak="false">map(*)</code> is assumed.</p>
                        </item>
                        <item>
                           <p>The expression <var>EXPR</var> is evaluated, and its value is converted
                     to the declared map type <var>MT</var> by applying the <termref def="dt-coercion-rules"/>.
                     A type error <errorref class="TY" code="0004"/> is raised if the result is not
                        a <termref def="dt-singleton"/> map.
                     Call the resulting (coerced) value <var>V</var>.</p>
                        </item>
                        <item>
                           <p>Each variable <var>A/i</var> (for <var>i</var> in 1 to <var>n</var>)
                     is effectively replaced by a <nt def="prod-xquery40-LetValueBinding">LetValueBinding<!--$spec = xquery40--></nt>
                        of the form <code nobreak="false">let <var>A/i</var> as <var>T/i</var> := map:get(<var>V</var>, "<var>N/i</var>", ())</code>,
                        where <var>N/i</var> is the local part of the name of the variable <var>A/i</var>.
                     That is, a <term>range variable</term> named <var>A/i</var> is declared, whose <term>binding sequence</term>
                     is the value of the map entry in <var>V</var> whose key is an <code nobreak="false">xs:string</code> (or <code nobreak="false">xs:anyURI</code> or <code nobreak="false">xs:untypedAtomic</code>)
                        equal to the local part of the variable name, after coercion to the type <var>T/i</var> if specified.
                     If <var>T/i</var> is absent, no further coercion takes place (the default is effectively
                     <code nobreak="false">item()*</code>).</p>
                           <note>
                              <p>If there is no entry in the map with a key corresponding to the variable
                           name, then the variable
                        <var>A/i</var> is bound to the empty sequence. This will cause a type error if
                        type <var>T/i</var> does not permit the empty sequence.</p>
                           </note>
                           <note>
                              <p>It is not possible to use this mechanism to bind variables to values
                        in a map unless the keys in the map are strings in the form of <code nobreak="false">NCNames</code>.</p>
                           </note>
                           <example>
                              <head>Example:</head>
                              <p>The expression:</p>
                              <eg xml:space="preserve">let ${ $a, $b as xs:integer, $local:c } := { "a": 2, "b": 4, "c": 6, "d": 8 }
return $a + $b + $local:c</eg>
                              <p>is expanded to:</p>
                              <eg xml:space="preserve">let $temp := { "a": 2, "b": 4, "c": 6 }
let $a := map:get($temp, "a", ())
let $b as xs:integer := map:get($temp, "b", ())
let $local:c := map:get($temp, "c", ())
return $a + $b + $local:c</eg>
                              <p>where <code nobreak="false">$temp</code> is some variable name that is otherwise unused.</p>
                           </example>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>The effect of the <nt def="doc-xquery40-LetClause">LetClause<!--$spec = xquery40--></nt> is to add
             one or more variable bindings to the tuple stream. Specifically, each
             <term>range variable</term> declared within the <code nobreak="false">LetClause</code>
             is bound to its corresponding <term>binding sequence</term>, and 
             the resulting variable binding is added to the current tuple, replacing
             any existing variable binding with the same variable name.</p>
                     <p>If the <code nobreak="false">LetClause</code> is the initial clause in a FLWOR expression, 
                it creates an initial tuple for the tuple stream, containing these variable
                bindings. This tuple stream serves as input to the next clause in the FLWOR expression.</p>
                     <p>If the <code nobreak="false">LetClause</code> is an intermediate clause in a FLWOR expression, 
               it adds the relevant variable bindings to each tuple in the input tuple stream. 
               The resulting tuples become the output tuple stream of the <code nobreak="false">let</code> clause.</p>
                     <p>The number of tuples in the output tuple stream of an intermediate <code nobreak="false">let</code> 
               clause is the same as the number of tuples in the input tuple stream. 
               The number of variable bindings in the output tuples is always greater than
               the number of variable bindings in the input tuples, unless the input tuples 
               already contain bindings for every variable binding created by the <code nobreak="false">LetClause</code>; 
               in this case, the new binding for any given variable name occludes (replaces) 
               an earlier binding for that variable name, and the number of bindings is unchanged.</p>
                  </item>
               </olist>
               <p>The semantics of type declarations are further defined in <specref ref="id-binding-rules"/>.</p>
               <p>The following code fragment illustrates how a <code nobreak="false">for</code> clause 
               and a <code nobreak="false">let</code> clause can be used together. The <code nobreak="false">for</code> 
               clause produces an initial tuple stream containing a binding for variable 
               <code nobreak="false">$d</code> to each department number found in a given input document. 
               The <code nobreak="false">let</code> clause adds an additional binding to each tuple, 
               binding variable <code nobreak="false">$e</code> to a sequence of employees whose department 
               number matches the value of <code nobreak="false">$d</code> in that tuple.</p>
               <eg xml:space="preserve">for $d in doc("depts.xml")/depts/deptno
let $e := doc("emps.xml")/emps/emp[deptno eq $d]</eg>
            </div3>
            <div3 id="id-windows" role="xquery">
               <head>Window Clause</head>
               <changes>
                  <change issue="452" PR="483" date="2023-05-18">
                  The <code nobreak="false">start</code> clause in window expressions has become optional, as well as
                  the <code nobreak="false">when</code> keyword and its associated expression.
               </change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-WindowClause">
                     <lhs>WindowClause</lhs>
                     <rhs>"for"  (<nt def="prod-xquery40-TumblingWindowClause">TumblingWindowClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SlidingWindowClause">SlidingWindowClause<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-TumblingWindowClause">
                     <lhs>TumblingWindowClause</lhs>
                     <rhs>"tumbling"  "window"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-VarNameAndType">
                     <lhs>VarNameAndType</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-TypeDeclaration">
                     <lhs>TypeDeclaration</lhs>
                     <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-WindowStartCondition">
                     <lhs>WindowStartCondition</lhs>
                     <rhs>"start"  <nt def="prod-xquery40-WindowVars">WindowVars<!--$idref_lang_part = xquery40- --></nt>  ("when"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-WindowVars">
                     <lhs>WindowVars</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CurrentVar">CurrentVar<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-PreviousVar">PreviousVar<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-NextVar">NextVar<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-CurrentVar">
                     <lhs>CurrentVar</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-VarName">
                     <lhs>VarName</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-PositionalVar">
                     <lhs>PositionalVar</lhs>
                     <rhs>"at"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-PreviousVar">
                     <lhs>PreviousVar</lhs>
                     <rhs>"previous"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-NextVar">
                     <lhs>NextVar</lhs>
                     <rhs>"next"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-WindowEndCondition">
                     <lhs>WindowEndCondition</lhs>
                     <rhs>"only"?  "end"  <nt def="prod-xquery40-WindowVars">WindowVars<!--$idref_lang_part = xquery40- --></nt>  ("when"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-WindowClause-SlidingWindowClause">
                     <lhs>SlidingWindowClause</lhs>
                     <rhs>"sliding"  "window"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>Like a <code nobreak="false">for</code> clause, a <code nobreak="false">window</code> clause
iterates over its <termref def="dt-binding-sequence">binding
sequence</termref> and generates a sequence of tuples. In the case of
a <code nobreak="false">window</code> clause, each tuple represents a window. <termdef term="window" id="dt-window">A <term>window</term> is a sequence of
consecutive items drawn from the <termref def="dt-binding-sequence">binding sequence</termref>.</termdef> Each
window is represented by at least one and at most nine bound
variables. The variables have user-specified names, but their roles
are as follows:</p>
               <ulist>
                  <item>
                     <p>
                        <emph>Window-variable:</emph> Bound to the sequence of
  items from the <termref def="dt-binding-sequence">binding
  sequence</termref> that comprise the window.</p>
                  </item>
                  <item>
                     <p>
                        <emph>Start-item:</emph> (Optional) Bound to the first item
  in the window.</p>
                  </item>
                  <item>
                     <p>
                        <emph>Start-item-position:</emph> (Optional) Bound to the
  ordinal position of the first window item in the <termref def="dt-binding-sequence">binding
  sequence</termref>. <emph>Start-item-position</emph> is a <termref def="dt-positional-variable">positional variable</termref>; hence, its type
  is <code nobreak="false">xs:integer</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <emph>Start-previous-item:</emph> (Optional) Bound to the
  item in the <termref def="dt-binding-sequence">binding
  sequence</termref> that precedes the first item in the window (empty
  sequence if none).</p>
                  </item>
                  <item>
                     <p>
                        <emph>Start-next-item:</emph> (Optional) Bound to the item
  in the <termref def="dt-binding-sequence">binding sequence</termref>
  that follows the first item in the window (empty sequence if
  none).</p>
                  </item>
                  <item>
                     <p>
                        <emph>End-item:</emph> (Optional) Bound to the last item in
  the window.</p>
                  </item>
                  <item>
                     <p>
                        <emph>End-item-position:</emph> (Optional) Bound to the
  ordinal position of the last window item in the <termref def="dt-binding-sequence">binding
  sequence</termref>. <emph>End-item-position</emph> is a <termref def="dt-positional-variable">positional variable</termref>; hence, its type
  is <code nobreak="false">xs:integer</code>.
                  </p>
                  </item>
                  <item>
                     <p>
                        <emph>End-previous-item:</emph> (Optional) Bound to the
  item in the <termref def="dt-binding-sequence">binding
  sequence</termref> that precedes the last item in the window (empty
  sequence if none).</p>
                  </item>
                  <item>
                     <p>
                        <emph>End-next-item:</emph> (Optional) Bound to the item in
  the <termref def="dt-binding-sequence">binding sequence</termref>
  that follows the last item in the window (empty sequence if
  none).</p>
                  </item>
               </ulist>
               <p>All variables in a <code nobreak="false">window</code> clause must have distinct names;
 otherwise a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0103"/>.</p>
               <p>The following is an example of a <code nobreak="false">window</code> clause that
binds nine variables to the roles listed above. In this example, the
variables are named <code nobreak="false">$w</code>, <code nobreak="false">$s</code>,
<code nobreak="false">$spos</code>, <code nobreak="false">$sprev</code>, <code nobreak="false">$snext</code>,
<code nobreak="false">$e</code>, <code nobreak="false">$epos</code>, <code nobreak="false">$eprev</code>, and
<code nobreak="false">$enext</code> respectively. A <code nobreak="false">window</code> clause always
binds the window variable, but typically binds only a subset of the
other variables.</p>
               <eg xml:space="preserve">for tumbling window $w in (2, 4, 6, 8, 10)
  start $s at $spos previous $sprev next $snext when true() 
  end   $e at $epos previous $eprev next $enext when true()</eg>
               <p>Windows are
created by iterating over the items in the <termref def="dt-binding-sequence">binding sequence</termref>, in order,
identifying the start item and the end item of each window by
evaluating the <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt> and the <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$spec = xquery40--></nt>. Each of these
conditions is satisfied if the <termref def="dt-ebv">effective boolean
value</termref> of the expression following the <code nobreak="false">when</code>
keyword is <code nobreak="false">true</code>.

The start item of the window is an item that satisfies the <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt> (see <specref ref="id-tumbling-windows"/> and <specref ref="id-sliding-windows"/> for a more complete explanation.) The end item of the window is the first item in the <termref def="dt-binding-sequence">binding sequence</termref>, beginning with the start item, that satisfies the <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$spec = xquery40--></nt> (again, see <specref ref="id-tumbling-windows"/> and <specref ref="id-sliding-windows"/> for more details.) Each window contains its start item, its end
item, and all items that occur between them in the <termref def="dt-binding-sequence">binding sequence</termref>.
If the end item is the start item, then the window contains only one
item.  If a start item is identified, but no following item in the <termref def="dt-binding-sequence">binding sequence</termref> satisfies the <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$spec = xquery40--></nt>, then the <code nobreak="false">only</code> keyword determines whether a window is
generated: if <code nobreak="false">only end</code> is specified, then no window is
generated; otherwise, the end item is set to the last item in the
<termref def="dt-binding-sequence">binding sequence</termref> and a window is generated.</p>
               <p>In the above example, the <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt> and <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$spec = xquery40--></nt> are both <code nobreak="false">true</code>,
which causes each item in the <termref def="dt-binding-sequence">binding sequence</termref> to be in a separate window. 
Typically, the <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt> and <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$spec = xquery40--></nt> are expressed in terms of bound variables. For example, the following <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt> might be used to start a new window for every item in the <termref def="dt-binding-sequence">binding sequence</termref> that is larger than both the previous item and the following item:</p>
               <eg xml:space="preserve">start $s previous $sprev next $snext
when  $s &gt; $sprev and $s &gt; $snext</eg>
               <p>The scoping rules for the variables bound by a <code nobreak="false">window</code> clause are as follows:</p>
               <ulist>
                  <item>
                     <p>In the <code nobreak="false">when</code>-expression of the <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt>, the following variables (identified here by their roles) are in scope (if bound): <emph>start-item, start-item-position, start-previous-item, start-next-item.</emph>
                     </p>
                  </item>
                  <item>
                     <p>In the <code nobreak="false">when</code>-expression of the <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$spec = xquery40--></nt>, the following variables (identified here by their roles) are in scope (if bound): <emph>start-item, start-item-position, start-previous-item, start-next-item, end-item, end-item-position, end-previous-item, end-next-item.</emph>
                     </p>
                  </item>
                  <item>
                     <p>In the clauses of the FLWOR expression that follow the <code nobreak="false">window</code> clause, all nine of the variables bound by the <code nobreak="false">window</code> clause (including <emph>window-variable</emph>) are in scope (if bound).</p>
                  </item>
               </ulist>
               <p>The <code nobreak="false">when</code> keyword of a condition and the associated expression is optional.
               If omitted, the expression defaults to <code nobreak="false">true</code>.
               If the complete <code nobreak="false">start</code> clause is omitted, no variables are bound and
               the expression also defaults to <code nobreak="false">true</code>.
               The <code nobreak="false">end</code> clause can be omitted only within a <nt def="prod-xquery40-TumblingWindowClause">TumblingWindowClause<!--$spec = xquery40--></nt>.</p>
               <p>In a <code nobreak="false">window</code> clause, the keyword <code nobreak="false">tumbling</code> or <code nobreak="false">sliding</code> determines the way in which the starting item of each window is identified, as explained in the following sections.</p>
               <div4 id="id-tumbling-windows">
                  <head>Tumbling Windows</head>
                  <p>If the window type is <code nobreak="false">tumbling</code>, then windows
never overlap. The search for the start of the first window begins at the beginning of the <termref def="dt-binding-sequence">binding sequence</termref>. After each window is generated, the search
for the start of the next window begins with the item in the <termref def="dt-binding-sequence">binding sequence</termref> that occurs after the ending item of the last generated
window. Thus, no item that occurs in one window can occur in another
window drawn from the same <termref def="dt-binding-sequence">binding sequence</termref> (unless the sequence contains the same item more than once). 
In a tumbling window clause,
the <code nobreak="false">end</code> clause is optional; if it is omitted, the
<code nobreak="false">start</code> clause is applied to identify all potential
starting items in the <termref def="dt-binding-sequence">binding sequence</termref>, and a window is constructed
for each starting item, including all items from that starting item up
to the item before the next window’s starting item, or the end of the
<termref def="dt-binding-sequence">binding sequence</termref>, whichever comes first.</p>
                  <p>The following examples illustrate the use of tumbling windows.</p>
                  <ulist>
                     <item>
                        <p>Show non-overlapping windows of three items.</p>
                        <eg role="parse-test" xml:space="preserve">for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)
  start at $s
  only end at $e when $e - $s eq 2
return &lt;window&gt;{ $w }&lt;/window&gt;</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">&lt;window&gt;2 4 6&lt;/window&gt;
&lt;window&gt;8 10 12&lt;/window&gt;</eg>
                     </item>
                     <item>
                        <p>Show averages of non-overlapping three-item windows.</p>
                        <eg role="parse-test" xml:space="preserve">
for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)
  start at $s
  only end at $e when $e - $s eq 2
return avg($w)</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">4 10</eg>
                     </item>
                     <item>
                        <p>Show first and last items in each window of three items.</p>
                        <eg role="parse-test" xml:space="preserve">for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)
  start $first at $s
  only end $last at $e when $e - $s eq 2
return &lt;window&gt;{ $first, $last }&lt;/window&gt;</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">&lt;window&gt;2 6&lt;/window&gt;
&lt;window&gt;8 12&lt;/window&gt;</eg>
                     </item>
                     <item>
                        <p>Show non-overlapping windows of up to three items (illustrates <code nobreak="false">end</code> clause without the <code nobreak="false">only</code> keyword).</p>
                        <eg role="parse-test" xml:space="preserve">for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)
  start at $s
  end at $e when $e - $s eq 2
return &lt;window&gt;{ $w }&lt;/window&gt;</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">&lt;window&gt;2 4 6&lt;/window&gt;
&lt;window&gt;8 10 12&lt;/window&gt;
&lt;window&gt;14&lt;/window&gt;</eg>
                     </item>
                     <item>
                        <p>Show non-overlapping windows of up to three items (illustrates use of <code nobreak="false">start</code> without explicit <code nobreak="false">end</code>).</p>
                        <eg role="parse-test" xml:space="preserve">for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)
  start at $s when $s mod 3 = 1
return &lt;window&gt;{ $w }&lt;/window&gt;</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">&lt;window&gt;2 4 6&lt;/window&gt;
&lt;window&gt;8 10 12&lt;/window&gt;
&lt;window&gt;14&lt;/window&gt;</eg>
                     </item>
                     <item>
                        <p>Show non-overlapping sequences starting with a number divisible by 3.</p>
                        <eg role="parse-test" xml:space="preserve">for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)
  start $first when $first mod 3 = 2
return &lt;window&gt;{ $w }&lt;/window&gt;</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">&lt;window&gt;2 4 6&lt;/window&gt;
&lt;window&gt;8 10 12&lt;/window&gt;
&lt;window&gt;14&lt;/window&gt;</eg>
                     </item>
                     <item>
                        <p>Show non-overlapping sequences ending with a number divisible by 3.</p>
                        <eg role="parse-test" xml:space="preserve">for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)
  end $last when $last mod 3 = 0
return &lt;window&gt;{ $w }&lt;/window&gt;</eg>
                        <p>Result (identical to the result of the previous query):</p>
                        <eg xml:space="preserve">&lt;window&gt;2 4 6&lt;/window&gt;
&lt;window&gt;8 10 12&lt;/window&gt;
&lt;window&gt;14&lt;/window&gt;</eg>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-sliding-windows">
                  <head>Sliding Windows</head>
                  <p>If the window type is <code nobreak="false">sliding window</code>, then windows may
overlap. Every item in the <termref def="dt-binding-sequence">binding sequence</termref> that satisfies the <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$spec = xquery40--></nt> is the starting item of a new window. Thus, a given
item may be found in multiple windows drawn from the same <termref def="dt-binding-sequence">binding sequence</termref>.</p>
                  <p>The following examples illustrate the use of sliding windows.</p>
                  <ulist>
                     <item>
                        <p>Show windows of three items.</p>
                        <eg role="parse-test" xml:space="preserve">for sliding window $w in (2, 4, 6, 8, 10, 12, 14)
  start at $s
  only end at $e when $e - $s eq 2
return &lt;window&gt;{ $w }&lt;/window&gt;</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">&lt;window&gt;2 4 6&lt;/window&gt;
&lt;window&gt;4 6 8&lt;/window&gt;
&lt;window&gt;6 8 10&lt;/window&gt;
&lt;window&gt;8 10 12&lt;/window&gt;
&lt;window&gt;10 12 14&lt;/window&gt;</eg>
                     </item>
                     <item>
                        <p>Show moving averages of three items.</p>
                        <eg role="parse-test" xml:space="preserve">for sliding window $w in (2, 4, 6, 8, 10, 12, 14)
  start at $s
  only end at $e when $e - $s eq 2
return avg($w)</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">4 6 8 10 12</eg>
                     </item>
                     <item>
                        <p>Show overlapping windows of up to three items (illustrates <code nobreak="false">end</code> clause without the <code nobreak="false">only</code> keyword).</p>
                        <eg role="parse-test" xml:space="preserve">for sliding window $w in (2, 4, 6, 8, 10, 12, 14)
  start at $s
  end at $e when $e - $s eq 2
return &lt;window&gt;{ $w }&lt;/window&gt;</eg>
                        <p>Result:</p>
                        <eg xml:space="preserve">&lt;window&gt;2 4 6&lt;/window&gt;
&lt;window&gt;4 6 8&lt;/window&gt;
&lt;window&gt;6 8 10&lt;/window&gt;
&lt;window&gt;8 10 12&lt;/window&gt;
&lt;window&gt;10 12 14&lt;/window&gt;
&lt;window&gt;12 14&lt;/window&gt;
&lt;window&gt;14&lt;/window&gt;</eg>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-effects-of-window-clauses">
                  <head>Effects of Window Clauses on the Tuple Stream</head>
                  <p>The effects of a <code nobreak="false">window</code> clause on the tuple stream are similar to the effects of a <code nobreak="false">for</code> clause. As described in <specref ref="id-windows"/>, a <code nobreak="false">window</code> clause generates zero or more windows, each of which is represented by at least one and at most nine bound variables.</p>
                  <p>If the <code nobreak="false">window</code> clause is the initial clause in a FLWOR expression, 
                  the bound variables that describe each window become an output tuple. 
                  These tuples form the initial tuple stream that serves as input to the next clause of the FLWOR expression. 
                  The order of tuples in the tuple stream is the
                  order in which their start items appear in the <termref def="dt-binding-sequence">binding sequence</termref>. The cardinality of the tuple stream is equal to the number of windows.</p>
                  <p>If a <code nobreak="false">window</code> clause is an intermediate clause in a FLWOR expression, each input tuple generates zero or more output tuples, each consisting of  the original bound variables of the input tuple plus the new bound variables that represent one of the generated windows. For each tuple <emph>T</emph> in the input tuple stream, the output tuple stream will contain <emph>N<sub>T</sub>
                     </emph> tuples, where <emph>N<sub>T</sub>
                     </emph> is the number of windows generated by the <code nobreak="false">window</code> clause, 
                  given the bindings in the input tuple <emph>T</emph>. Input tuples for which no windows 
                  are generated are not represented in the output tuple stream. 
                  The order of tuples in the output stream is determined primarily by the order of the 
                  input tuples from which they were derived, and secondarily by the order in which their 
                  start items appear in the <termref def="dt-binding-sequence">binding sequence</termref>. </p>
                  <p>The following example illustrates a <code nobreak="false">window</code> clause that is the initial clause in a FLWOR expression. The example is based on input data that consists of a sequence of closing stock prices for a specific company. For this example we assume the following input data (assume that the <code nobreak="false">price</code> elements have a validated type of <code nobreak="false">xs:decimal</code>):</p>
                  <eg xml:space="preserve">&lt;stock&gt;
  &lt;closing&gt; &lt;date&gt;2008-01-01&lt;/date&gt; &lt;price&gt;105&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;date&gt;2008-01-02&lt;/date&gt; &lt;price&gt;101&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;date&gt;2008-01-03&lt;/date&gt; &lt;price&gt;102&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;date&gt;2008-01-04&lt;/date&gt; &lt;price&gt;103&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;date&gt;2008-01-05&lt;/date&gt; &lt;price&gt;102&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;date&gt;2008-01-06&lt;/date&gt; &lt;price&gt;104&lt;/price&gt; &lt;/closing&gt;
&lt;/stock&gt;</eg>
                  <p>A user wishes to find “run-ups,” which are defined as sequences of dates that begin with a “low” and end with a “high” price (that is, the stock price begins to rise on the first day of the run-up, and continues to rise or remain even through the last day of the run-up.) The following query uses a tumbling window to find run-ups in the input data:</p>
                  <eg role="parse-test" xml:space="preserve">for tumbling window $w in //closing
   start $first next $second when $first/price &lt; $second/price
   end $last next $beyond when $last/price &gt; $beyond/price
return
  &lt;run-up&gt;
    &lt;start-date&gt;{ data($first/date) }&lt;/start-date&gt;
    &lt;start-price&gt;{ data($first/price) }&lt;/start-price&gt;
    &lt;end-date&gt;{ data($last/date) }&lt;/end-date&gt;
    &lt;end-price&gt;{ data($last/price) }&lt;/end-price&gt;
  &lt;/run-up&gt;</eg>
                  <p>For our sample input data, this <code nobreak="false">tumbling window</code> clause generates a tuple stream consisting of two tuples, each representing a window and containing five bound variables named <code nobreak="false">$w</code>, <code nobreak="false">$first</code>, <code nobreak="false">$second</code>, <code nobreak="false">$last</code>, and <code nobreak="false">$beyond</code>. The <code nobreak="false">return</code> clause is evaluated for each of these tuples, generating the following query result:</p>
                  <eg xml:space="preserve">&lt;run-up&gt;
  &lt;start-date&gt;2008-01-02&lt;/start-date&gt;
  &lt;start-price&gt;101&lt;/start-price&gt;
  &lt;end-date&gt;2008-01-04&lt;/end-date&gt;
  &lt;end-price&gt;103&lt;/end-price&gt;
&lt;/run-up&gt;
&lt;run-up&gt;
  &lt;start-date&gt;2008-01-05&lt;/start-date&gt;
  &lt;start-price&gt;102&lt;/start-price&gt;
  &lt;end-date&gt;2008-01-06&lt;/end-date&gt;
  &lt;end-price&gt;104&lt;/end-price&gt;
&lt;/run-up&gt;</eg>
                  <p>The following example illustrates a <code nobreak="false">window</code> clause that is an intermediate clause in a FLWOR expression. In this example, the input data contains closing stock prices for several different companies, each identified by a three-letter symbol. We assume the following input data (again assuming that the type of the <code nobreak="false">price</code> element is <code nobreak="false">xs:decimal</code>):</p>
                  <eg xml:space="preserve">&lt;stocks&gt;
  &lt;closing&gt; &lt;symbol&gt;ABC&lt;/symbol&gt; &lt;date&gt;2008-01-01&lt;/date&gt; &lt;price&gt;105&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;DEF&lt;/symbol&gt; &lt;date&gt;2008-01-01&lt;/date&gt; &lt;price&gt;057&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;ABC&lt;/symbol&gt; &lt;date&gt;2008-01-02&lt;/date&gt; &lt;price&gt;101&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;DEF&lt;/symbol&gt; &lt;date&gt;2008-01-02&lt;/date&gt; &lt;price&gt;054&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;ABC&lt;/symbol&gt; &lt;date&gt;2008-01-03&lt;/date&gt; &lt;price&gt;102&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;DEF&lt;/symbol&gt; &lt;date&gt;2008-01-03&lt;/date&gt; &lt;price&gt;056&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;ABC&lt;/symbol&gt; &lt;date&gt;2008-01-04&lt;/date&gt; &lt;price&gt;103&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;DEF&lt;/symbol&gt; &lt;date&gt;2008-01-04&lt;/date&gt; &lt;price&gt;052&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;ABC&lt;/symbol&gt; &lt;date&gt;2008-01-05&lt;/date&gt; &lt;price&gt;101&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;DEF&lt;/symbol&gt; &lt;date&gt;2008-01-05&lt;/date&gt; &lt;price&gt;055&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;ABC&lt;/symbol&gt; &lt;date&gt;2008-01-06&lt;/date&gt; &lt;price&gt;104&lt;/price&gt; &lt;/closing&gt;
  &lt;closing&gt; &lt;symbol&gt;DEF&lt;/symbol&gt; &lt;date&gt;2008-01-06&lt;/date&gt; &lt;price&gt;059&lt;/price&gt; &lt;/closing&gt;
&lt;/stocks&gt;</eg>
                  <p>As in the previous example, we want to find "run-ups," which are defined as sequences of dates that begin with a "low" and end with a "high" price for a specific company. In this example, however, the input data consists of stock prices for multiple companies. Therefore it is necessary to isolate the stock prices of each company before forming windows. This can be accomplished by an initial <code nobreak="false">for</code> and <code nobreak="false">let</code> clause, followed by a <code nobreak="false">window</code> clause, as follows:</p>
                  <eg role="parse-test" xml:space="preserve">for $symbol in distinct-values(//symbol)
let $closings := //closing[symbol = $symbol]
for tumbling window $w in $closings
  start $first next $second when $first/price &lt; $second/price
  end $last next $beyond when $last/price &gt; $beyond/price
return
  &lt;run-up symbol="{ $symbol }"&gt;
    &lt;start-date&gt;{ data($first/date) }&lt;/start-date&gt;
    &lt;start-price&gt;{ data($first/price) }&lt;/start-price&gt;
    &lt;end-date&gt;{ data($last/date) }&lt;/end-date&gt;
    &lt;end-price&gt;{ data($last/price) }&lt;/end-price&gt;
  &lt;/run-up&gt;</eg>
                  <note>
                     <p>In the above example, the <code nobreak="false">for</code> and <code nobreak="false">let</code> clauses could be rewritten as follows:</p>
                     <eg xml:space="preserve">for $closings in //closing
let $symbol := $closings/symbol
group by $symbol</eg>
                     <p>The <code nobreak="false">group by</code> clause is described in <specref ref="id-group-by"/>.</p>
                  </note>
                  <p>The <code nobreak="false">for</code> and <code nobreak="false">let</code> clauses in this query generate an initial tuple stream consisting of two tuples. In the first tuple, <code nobreak="false">$symbol</code> is bound to "ABC" and <code nobreak="false">$closings</code> is bound to the sequence of <code nobreak="false">closing</code> elements for company ABC. In the second tuple, <code nobreak="false">$symbol</code> is bound to "DEF" and <code nobreak="false">$closings</code> is bound to the sequence of <code nobreak="false">closing</code> elements for company DEF.</p>
                  <p>The <code nobreak="false">window</code> clause operates on this initial tuple stream, generating two windows for the first tuple and two windows for the second tuple. The result is a tuple stream consisting of four tuples, each with the following bound variables: <code nobreak="false">$symbol</code>, <code nobreak="false">$closings</code>, <code nobreak="false">$w</code>, <code nobreak="false">$first</code>, <code nobreak="false">$second</code>, <code nobreak="false">$last</code>, and <code nobreak="false">$beyond</code>. The <code nobreak="false">return</code> clause is then evaluated for each of these tuples, generating the following query result:</p>
                  <eg xml:space="preserve">&lt;run-up symbol="ABC"&gt;
   &lt;start-date&gt;2008-01-02&lt;/start-date&gt;
   &lt;start-price&gt;101&lt;/start-price&gt;
   &lt;end-date&gt;2008-01-04&lt;/end-date&gt;
   &lt;end-price&gt;103&lt;/end-price&gt;
&lt;/run-up&gt;
&lt;run-up symbol="ABC"&gt;
   &lt;start-date&gt;2008-01-05&lt;/start-date&gt;
   &lt;start-price&gt;101&lt;/start-price&gt;
   &lt;end-date&gt;2008-01-06&lt;/end-date&gt;
   &lt;end-price&gt;104&lt;/end-price&gt;
&lt;/run-up&gt;
&lt;run-up symbol="DEF"&gt;
   &lt;start-date&gt;2008-01-02&lt;/start-date&gt;
   &lt;start-price&gt;054&lt;/start-price&gt;
   &lt;end-date&gt;2008-01-03&lt;/end-date&gt;
   &lt;end-price&gt;056&lt;/end-price&gt;
&lt;/run-up&gt;
&lt;run-up symbol="DEF"&gt;
   &lt;start-date&gt;2008-01-04&lt;/start-date&gt;
   &lt;start-price&gt;052&lt;/start-price&gt;
   &lt;end-date&gt;2008-01-06&lt;/end-date&gt;
   &lt;end-price&gt;059&lt;/end-price&gt;
&lt;/run-up&gt;</eg>
               </div4>
            </div3>
            <div3 id="id-where" role="xquery">
               <head>Where Clause</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-WhereClause">
                     <lhs>WhereClause</lhs>
                     <rhs>"where"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WhereClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>A <code nobreak="false">where</code> clause serves as a filter for the tuples in its input tuple stream. The expression in the <code nobreak="false">where</code> clause, called the <term>where-expression</term>, is evaluated once for
               each of these tuples. If the <termref def="dt-ebv">effective boolean value</termref> of the
               where-expression is <code nobreak="false">true</code>, the tuple is retained in the output tuple stream; otherwise the tuple is discarded.</p>
               <p>Examples:</p>
               <ulist>
                  <item>
                     <p>This example illustrates the effect of a <code nobreak="false">where</code> clause on a tuple stream:</p>
                     <p>Input tuple stream:</p>
                     <eg xml:space="preserve">($a = 5, $b = 11)
($a = 91, $b = 42)
($a = 17, $b = 30)
($a = 85, $b = 63)</eg>
                     <p>
                        <code nobreak="false">where</code> clause:</p>
                     <eg xml:space="preserve">where $a &gt; $b</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($a = 91, $b = 42)
($a = 85, $b = 63)</eg>
                  </item>
                  <item>
                     <p>The following query illustrates how a <code nobreak="false">where</code> clause might be used with a <termref def="dt-positional-variable">positional variable</termref> to perform sampling on an input sequence. The query returns one value out of each one hundred input values.</p>
                     <eg role="parse-test" xml:space="preserve"><phrase role="parse-test">for $x at $i in $input
where $i mod 100 = 0
return $x</phrase>
                  </eg>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-while" diff="add" at="issue187" role="xquery">
               <head>While Clause</head>
               <changes>
                  <change issue="187" PR="943" date="2024-02-06">
                  A FLWOR expression may now include a <code nobreak="false">while</code> clause,
               which causes early exit from the iteration when a condition is encountered.
               </change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-WhileClause">
                     <lhs>WhileClause</lhs>
                     <rhs>"while"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-WhileClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>A <code nobreak="false">while</code> clause serves as a filter for the tuples 
               in its input tuple stream. The expression in the while clause, 
               called the <code nobreak="false">while-expression</code>, is evaluated once for each of these tuples. 
               If the <termref def="dt-ebv">effective boolean value</termref> 
               of the <code nobreak="false">while-expression</code> is true, the 
               tuple is retained in the output tuple stream; otherwise the tuple 
               and all subsequent tuples in the stream are discarded.</p>
               <p>Examples:</p>
               <ulist>
                  <item>
                     <p>This example illustrates the effect of a <code nobreak="false">while</code> clause on a tuple stream.</p>
                     <p>Input tuple stream:</p>
                     <eg xml:space="preserve">($a = 13, $b = 11)
($a = 91, $b = 42)
($a = 17, $b = 30)
($a = 85, $b = 63)</eg>
                     <p>while clause:</p>
                     <eg xml:space="preserve">while $a &gt; $b</eg>
                     <p> Output tuple stream:</p>
                     <eg xml:space="preserve">($a = 13, $b = 11)
($a = 91, $b = 42)</eg>
                  </item>
                  <item>
                     <p>The following query illustrates how a <code nobreak="false">while</code> clause might be used to 
                     extract all items in an input sequence before the first one that 
                     fails to satisfy some condition. In this case it selects the 
                     leading <code nobreak="false">para</code> elements in the input sequence, stopping 
                     before the first element that is not a <code nobreak="false">para</code> element.
                  </p>
                     <eg xml:space="preserve">for $x in $section/*
while $x[self::para]
return $x</eg>
                  </item>
                  <item>
                     <p>The following query illustrates how a <code nobreak="false">while</code> clause might be used to 
                     limit the number of items returned in the query result.
                  </p>
                     <eg xml:space="preserve">for $x in $section/para
where contains($x, 'the')
count $total
while $total le 10
return $x</eg>
                     <p>In this example a <code nobreak="false">where</code> clause would have exactly the same effect,
                  but might require a smarter optimizer to deliver the same performance.</p>
                  </item>
               </ulist>
               <note>
                  <p>Although the semantics are described in terms of discarding 
                  all the tuples following the first one that fails to match 
                  the condition, a practical implementation is likely to avoid 
                  evaluating those tuples, thus giving an "early exit" from 
                  the iteration performed by the FLWOR expression.
               </p>
               </note>
               <note>
                  <p>The expression <code nobreak="false">for $i in $input while $i le 3</code> differs
               from the expression <code nobreak="false">subsequence-where($input, to := fn {. gt 3 })</code> in that
               the <code nobreak="false">while</code> expression drops the first item that is greater than 3,
               while the <code nobreak="false">subsequence-where</code> expression retains it.</p>
               </note>
               <note>
                  <p>The effect of the <code nobreak="false">while</code> clause is unpredictable in cases
            where the ordering of the tuple stream is unpredictable. This can happen, for example,
            when iterating over the entries in a map.</p>
               </note>
            </div3>
            <div3 id="id-count" role="xquery">
               <head>Count Clause</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-CountClause">
                     <lhs>CountClause</lhs>
                     <rhs>"count"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CountClause-VarName">
                     <lhs>VarName</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CountClause-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>The purpose of a <code nobreak="false">count</code> clause is to enhance the tuple
stream with a new variable that is bound, in each tuple, to the
ordinal position of that tuple in the tuple stream. The name of the
new variable is specified in the <code nobreak="false">count</code> clause. Its type
            is implicitly <code nobreak="false">xs:integer</code>.</p>
               <p>The output tuple stream of a <code nobreak="false">count</code> clause is the same
as its input tuple stream, with each tuple enhanced by one additional
variable that is bound to the ordinal position of that tuple in the
tuple stream. However, if the name of the new variable is the same as
the name of an existing variable in the input tuple stream, the new
variable occludes (replaces) the existing variable of the same name,
and the number of bound variables in each tuple is unchanged.</p>
               <p>The following examples illustrate uses of the <code nobreak="false">count</code> clause:</p>
               <ulist>
                  <item>
                     <p>This example illustrates the effect of a <code nobreak="false">count</code> clause on an input tuple stream:</p>
                     <p>Input tuple stream:</p>
                     <eg xml:space="preserve">($name = "Bob", $age = 21)
($name = "Carol", $age = 19)
($name = "Ted", $age = 20)
($name = "Alice", $age = 22)</eg>
                     <p>
                        <code nobreak="false">count</code> clause:</p>
                     <eg xml:space="preserve">count $counter</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($name = "Bob", $age = 21, $counter = 1)
($name = "Carol", $age = 19, $counter = 2)
($name = "Ted", $age = 20, $counter = 3)
($name = "Alice", $age = 22, $counter = 4)</eg>
                  </item>
                  <item>
                     <p>This example illustrates how a counter might be used to filter the result of a query. The query ranks products in order by decreasing sales, and returns the three products with the highest sales. Assume that the variable <code nobreak="false">$products</code> is bound to a sequence of <code nobreak="false">product</code> elements, each of which has <code nobreak="false">name</code> and <code nobreak="false">sales</code> child-elements.</p>
                     <eg role="parse-test" xml:space="preserve">for $p in $products
order by $p/sales descending
count $rank
while $rank &lt;= 3
return &lt;product rank="{ $rank }"&gt;{ $p/name, $p/sales }&lt;/product&gt;</eg>
                     <p>The result of this query has the following structure:</p>
                     <eg xml:space="preserve">&lt;product rank="1"&gt;
  &lt;name&gt;Toaster&lt;/name&gt;
  &lt;sales&gt;968&lt;/sales&gt;
&lt;/product&gt;
&lt;product rank="2"&gt;
  &lt;name&gt;Blender&lt;/name&gt;
  &lt;sales&gt;520&lt;/sales&gt;
&lt;/product&gt;
&lt;product rank="3"&gt;
  &lt;name&gt;Can Opener&lt;/name&gt;
  &lt;sales&gt;475&lt;/sales&gt;
&lt;/product&gt;</eg>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-group-by" role="xquery">
               <head>Group By Clause</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-GroupByClause">
                     <lhs>GroupByClause</lhs>
                     <rhs>"group"  "by"  (<nt def="prod-xquery40-GroupingSpec">GroupingSpec<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-GroupingSpec">
                     <lhs>GroupingSpec</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?  ("collation"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-VarName">
                     <lhs>VarName</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-TypeDeclaration">
                     <lhs>TypeDeclaration</lhs>
                     <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-URILiteral">
                     <lhs>URILiteral</lhs>
                     <rhs>
                        <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-GroupByClause-StringLiteral">
                     <lhs>StringLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>
               </scrap>
               <p>A <code nobreak="false">group by</code> clause generates an output tuple stream in which each tuple represents a group of tuples from the input tuple stream
that have equivalent grouping keys. 
We will refer to the tuples in the input tuple stream as  <term>pre-grouping tuples</term>, and the tuples in the output tuple stream as <term>post-grouping tuples</term>.</p>
               <p>The <code nobreak="false">group by</code> clause assigns each pre-grouping tuple to a group, and
generates one post-grouping tuple for each group. 

In the post-grouping tuple for a group, each grouping key is represented by a variable that was specified in a <nt def="prod-xquery40-GroupingSpec">GroupingSpec<!--$spec = xquery40--></nt>, and every variable that appears in the pre-grouping tuples that were assigned to that group is represented by a variable of the same name, bound to a sequence of all values bound to the variable in any of these pre-grouping tuples.

Subsequent clauses in the FLWOR expression see only the variable
bindings in the post-grouping tuples; they no longer have access to
the variable bindings in the pre-grouping tuples. 
The number of post-grouping tuples is less than or equal to
the number of pre-grouping tuples.</p>
               <p>A <code nobreak="false">group by</code> clause contains one or more <nt def="prod-xquery40-GroupingSpec">grouping specifications<!--$spec = xquery40--></nt>, as shown in the grammar. <termdef id="dt-grouping-variable" term="grouping variable">Each grouping specification specifies one <term>grouping variable</term>, 
                     which refers to variable bindings in the pre-grouping tuples. The values of the grouping variables are used to assign pre-grouping tuples to groups.</termdef> Each grouping specification may optionally provide an expression to which its grouping variable is bound.  If no expression is provided, the grouping variable name must be equal (by the <code nobreak="false">eq</code> operator on <termref def="dt-expanded-qname">expanded QNames</termref>) to the name of a variable in the input tuple stream, and it refers to that variable; otherwise a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0094"/>. For each grouping specification that contains a binding expression, a <code nobreak="false">let</code> binding is created in the pre-grouping tuples, and the grouping variable refers to that <code nobreak="false">let</code> binding. For example, the clause:</p>
               <eg xml:space="preserve">group by $g1, $g2 := $expr1, $g3 := $expr2 collation "Spanish"</eg>
               <p>is semantically equivalent to the following sequence of clauses:</p>
               <eg xml:space="preserve">let $g2 := $expr1
let $g3 := $expr2
group by $g1, $g2, $g3 collation "Spanish"</eg>
               <p>The process of group formation proceeds as follows:

<olist>
                     <item>
                        <p>
                           <termdef term="grouping key" id="dt-grouping-key">The
  atomized value of a <termref def="dt-grouping-variable">grouping
  variable</termref> is called a <term>grouping key</term>.</termdef>
  For each pre-grouping tuple, the <termref def="dt-grouping-key">grouping keys</termref> are created by
  <termref def="dt-atomization">atomizing</termref> the values of the
  <termref def="dt-grouping-variable">grouping variables</termref> (in
  the post-grouping tuples, each grouping variable is set to the value
  of the corresponding grouping key, as discussed below).

  If the value of any <termref def="dt-grouping-variable">grouping variable</termref> consists of
  more than one item, a <termref def="dt-type-error">type
  error</termref> is raised <errorref class="TY" code="0004"/>. If a type declaration is present
  and the resulting atomized value is not an instance of the specified
  type, a <termref def="dt-type-error">type error</termref> is raised
  <errorref class="TY" code="0004"/>.</p>
                     </item>
                     <item>
                        <p>The input tuple stream is partitioned into groups of tuples
  whose grouping keys are <termref def="dt-equivalent-grouping-keys">equivalent</termref>. <termdef id="dt-equivalent-grouping-keys" term="equivalent grouping keys">Two
  tuples <var>T1</var> and <var>T2</var> have <term>equivalent
  grouping keys</term> if and only if, for each grouping variable
  <var>GV</var>, the atomized value of <var>GV</var> in <var>T1</var>
  is deep-equal to the atomized value of <var>GV</var> in
  <var>T2</var>, as defined by applying the function
  <function>fn:deep-equal</function> using the appropriate
  collation.</termdef>
                        </p>
                        <note diff="add" at="2023-12-05">
                           <p>The <function>fn:deep-equal</function> function has been changed
                     in XQuery 4.0 so that it is now transitive; the problem that existed
                     in earlier versions when comparing numeric values of different
                     types has thereby been resolved.</p>
                        </note>
                        <note>
                           <p>The atomized grouping key will always be either the empty
     sequence or a single atomic item. Defining equivalence by
     reference to the <function>fn:deep-equal</function> function
     ensures that the empty sequence is equivalent only to the empty
     sequence, that <code nobreak="false">NaN</code> is equivalent to
     <code nobreak="false">NaN</code>, that <code nobreak="false">xs:untypedAtomic</code> items are compared as
     strings, and that values from different 
                           <xtermref spec="DM40" ref="dt-type-family">atomic type families</xtermref>
     are considered non-equivalent.</p>
                        </note>
                     </item>
                     <item>
                        <p>The appropriate collation for comparing two grouping keys is the collation
   specified in the pertinent <nt def="prod-xquery40-GroupingSpec">GroupingSpec<!--$spec = xquery40--></nt> if present, or the default collation
                        from the <phrase diff="chg" at="2023-05-19">dynamic</phrase> context otherwise. 
                        If the collation is specified by a relative
   URI, that relative URI is  <termref def="dt-resolve-relative-uri">resolved to
   an absolute URI</termref> using the <termref def="dt-static-base-uri">Static Base URI</termref>.
   If the specified collation is not found in statically known
   collations, a static error is raised  <errorref class="ST" code="0076"/>.</p>
                     </item>
                  </olist>
               </p>
               <p>Each group of tuples produced by the above process results in one
post-grouping tuple. The pre-grouping tuples from which the group is
derived have <emph>equivalent</emph>
                  <termref def="dt-grouping-key">grouping keys</termref>, but these keys are not
necessarily identical (for example, the strings <code nobreak="false">"Frog"</code> and <code nobreak="false">"frog"</code>
might be <emph>equivalent</emph> according to the collation in use.)

In the post-grouping tuple, each <termref def="dt-grouping-variable">grouping variable</termref> is bound to the
value of the corresponding grouping key. 
</p>
               <p>In the post-grouping tuple generated for a given group, each
non-grouping variable is bound to a sequence containing the
concatenated values of that variable in all the pre-grouping tuples
that were assigned to that group. The values derived from individual tuples are
concatenated in a way that preserves the order of the pre-grouping
tuple stream.</p>
               <note>
                  <p>This behavior may be surprising to SQL programmers, since SQL reduces
the equivalent of a non-grouping variable to one representative
value. Consider the following query:</p>
                  <eg role="parse-test" xml:space="preserve">let $x := 64000
for $c in //customer
where $c/salary &gt; $x
group by $d := $c/department
return &lt;department name="{ $d }"&gt;
  Number of employees earning more than ${ $x } is { count($c) }
&lt;/department&gt;</eg>
                  <p>If there are three qualifying customers in the sales department this
evaluates to:</p>
                  <eg xml:space="preserve">
&lt;department name="sales"&gt;
  Number of employees earning more than $64000 64000 64000 is 3
&lt;/department&gt;</eg>
                  <p>In XQuery, each group is a sequence of items that match the group
by criteria—in a tree-structured language like XQuery, this is
convenient, because further structures can be built based on the items
in this sequence. Because there are three items in the group,
<code nobreak="false">$x</code> evaluates to a sequence of three items. To reduce this
to one item, use <code nobreak="false">fn:distinct-values()</code>:</p>
                  <eg role="parse-test" xml:space="preserve">
let $x := 64000
for $c in //customer
let $d := $c/department
where $c/salary &gt; $x
group by $d
return &lt;department name="{ $d }"&gt;
  Number of employees earning more than ${ distinct-values($x) } is { count($c) }
&lt;/department&gt;</eg>
               </note>
               <note>
                  <p>In general, the <termref def="dt-static-type">static
type</termref> of a variable in a post-grouping tuple is different
from the <termref def="dt-static-type">static type</termref> of the
variable with the same name in the pre-grouping
tuples.</p>
               </note>
               <p>The order in which tuples appear in the
post-grouping tuple stream is <termref def="dt-implementation-dependent">implementation-dependent</termref>.</p>
               <note>
                  <p>An
<code nobreak="false">order by</code> clause can be used to impose a value-based
ordering on the post-grouping tuple stream. Similarly, if it is
desired to impose a value-based ordering within a group (i.e., on the
sequence of items bound to a non-grouping variable), this can be
accomplished by a nested FLWOR expression that iterates over these
items and applies an <code nobreak="false">order by</code> clause. In some cases, a
value-based ordering within groups can be accomplished by applying an
<code nobreak="false">order by</code> clause on a non-grouping variable before
applying the <code nobreak="false">group by</code> clause.</p>
               </note>
               <p>A <code nobreak="false">group
by</code> clause rebinds all the variables in the input tuple
stream. The scopes of these variables are not affected by the
<code nobreak="false">group by</code> clause, but in post-grouping tuples the values
of the variables represent group properties rather than properties of
individual pre-grouping tuples.</p>
               <p>Examples:</p>
               <ulist>
                  <item>
                     <p>This example illustrates the effect of a <code nobreak="false">group by</code> clause on a tuple stream.</p>
                     <p>Input tuple stream:</p>
                     <eg xml:space="preserve">($storeno = &lt;storeno&gt;S101&lt;/storeno&gt;, $itemno = &lt;itemno&gt;P78395&lt;/itemno&gt;)
($storeno = &lt;storeno&gt;S102&lt;/storeno&gt;, $itemno = &lt;itemno&gt;P94738&lt;/itemno&gt;)
($storeno = &lt;storeno&gt;S101&lt;/storeno&gt;, $itemno = &lt;itemno&gt;P41653&lt;/itemno&gt;)
($storeno = &lt;storeno&gt;S102&lt;/storeno&gt;, $itemno = &lt;itemno&gt;P70421&lt;/itemno&gt;)
</eg>
                     <p>
                        <code nobreak="false">group by</code> clause:</p>
                     <eg xml:space="preserve">group by $storeno</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($storeno = S101, $itemno = (&lt;itemno&gt;P78395&lt;/itemno&gt;, &lt;itemno&gt;P41653&lt;/itemno&gt;))
($storeno = S102, $itemno = (&lt;itemno&gt;P94738&lt;/itemno&gt;, &lt;itemno&gt;P70421&lt;/itemno&gt;))</eg>
                  </item>
               </ulist>
               <ulist>
                  <item>
                     <p>This example and the ones that follow are based on two separate sequences of elements, named <code nobreak="false">$sales</code> and <code nobreak="false">$products</code>. We assume that the variable <code nobreak="false">$sales</code> is bound to a sequence of elements with the following structure:</p>
                     <eg xml:space="preserve">&lt;sales&gt;
  &lt;storeno&gt;S101&lt;/storeno&gt;
  &lt;itemno&gt;P78395&lt;/itemno&gt;
  &lt;qty&gt;125&lt;/qty&gt;
&lt;/sales&gt;</eg>
                     <p>We also assume that the variable <code nobreak="false">$products</code> is bound to a sequence of  elements with the following structure:</p>
                     <eg xml:space="preserve">&lt;product&gt;
  &lt;itemno&gt;P78395&lt;/itemno&gt;
  &lt;price&gt;25.00&lt;/price&gt;
  &lt;category&gt;Men's Wear&lt;/category&gt;
&lt;/product&gt;</eg>
                     <p>The simplest kind of grouping query has a single <termref def="dt-grouping-variable">grouping variable</termref>. The query in this example finds the total quantity of items sold by each store:</p>
                     <eg role="parse-test" xml:space="preserve">for $s in $sales
let $storeno := $s/storeno
group by $storeno
return &lt;store number="{ $storeno }" total-qty="{ sum($s/qty) }"/&gt;</eg>
                     <p>The result of this query is a sequence of elements with the following structure:</p>
                     <eg xml:space="preserve">&lt;store number="S101" total-qty="1550" /&gt;
&lt;store number="S102" total-qty="2125" /&gt;</eg>
                  </item>
                  <item>
                     <p>In a more realistic example, a user might be interested in the total revenue generated by each store for each product category. Revenue depends on both the quantity sold of various items and the price of each item. The following query joins the two input sequences and groups the resulting tuples by two <termref def="dt-grouping-variable">grouping variables</termref>:</p>
                     <eg role="parse-test" xml:space="preserve">
for $s in $sales
for $p in $products[itemno = $s/itemno]
let $revenue := $s/qty * $p/price
group by $storeno := $s/storeno, 
         $category := $p/category
return &lt;summary storeno="{ $storeno }"
                category="{ $category }"
                revenue="{ sum($revenue) }"/&gt;
</eg>
                     <p>The result of this query is a sequence of elements with the following structure:</p>
                     <eg xml:space="preserve">&lt;summary storeno="S101" category="Men's Wear" revenue="10185"/&gt;
&lt;summary storeno="S101" category="Stationery" revenue="4520"/&gt;
&lt;summary storeno="S102" category="Men's Wear" revenue="9750"/&gt;
&lt;summary storeno="S102" category="Appliances" revenue="22650"/&gt;
&lt;summary storeno="S102" category="Jewelry" revenue="30750"/&gt;</eg>
                  </item>
                  <item>
                     <p>The result of the previous example was a “flat” list of elements. A user might prefer the query result to be presented in the form of a  hierarchical report, grouped primarily by store (in order by store number) and secondarily by product category. Within each store, the user might want to see only those product categories whose total revenue exceeds $10,000, presented in descending order by their total revenue. This report is generated by the following query:</p>
                     <eg role="parse-test" xml:space="preserve">for $s1 in $sales
let $storeno := $s1/storeno
group by $storeno
order by $storeno
return &lt;store storeno="{ $storeno }"&gt;{
  for $s2 in $s1
  for $p in $products[itemno = $s2/itemno]
  let $category := $p/category
  let $revenue := $s2/qty * $p/price
  group by $category
  let $group-revenue := sum($revenue)
  where $group-revenue &gt; 10000
  order by $group-revenue descending
  return &lt;category name="{ $category }" revenue="{ $group-revenue }"/&gt;
}&lt;/store&gt;
</eg>
                     <p>The result of this example query has the following structure:</p>
                     <eg xml:space="preserve">&lt;store storeno="S101"&gt;
  &lt;category name="Men's Wear" revenue="10185"/&gt;
&lt;/store&gt;
&lt;store storeno="S102"&gt;
  &lt;category name="Jewelry" revenue="30750"/&gt;
  &lt;category name="Appliances" revenue="22650"/&gt;
&lt;/store&gt;</eg>
                  </item>
                  <item>
                     <p>The following example illustrates how to avoid a possible pitfall in writing grouping queries.</p>
                     <p>In each post-grouping tuple, all variables except for the grouping
variable are bound to sequences of items derived from all the
pre-grouping tuples from which the group was formed. For instance, in
the following query, <code nobreak="false">$high-price</code> is bound to a sequence
of items in the post-grouping tuple.</p>
                     <eg role="parse-test" xml:space="preserve">let $high-price := 1000
for $p in $products[price &gt; $high-price]
let $category := $p/category
group by $category
return &lt;category name="{ $category }"&gt;{
  count($p) || ' products have price greater than ' || $high-price || '.'
}&lt;/category&gt;</eg>
                     <p>If three products in the “Men’s Wear” category have prices greater than 1000, the result of this query might look (in part) like this:</p>
                     <eg xml:space="preserve">&lt;category name="Men’s Wear"&gt;
  3 products have price greater than 1000 1000 1000.
&lt;/category&gt;</eg>
                     <p>The repetition of "1000" in this query result is due to the fact that <code nobreak="false">$high-price</code> is not a <termref def="dt-grouping-variable">grouping variable</termref>. One way to avoid this repetition is to move the binding of <code nobreak="false">$high-price</code> to an outer-level FLWOR expression, as follows:</p>
                     <eg role="parse-test" xml:space="preserve">let $high-price := 1000
return (
  for $p in $products[price &gt; $high-price]
  let $category := $p/category
  group by $category
  return &lt;category name="{ $category }"&gt;{
    count($p) || ' products have price greater than ' || $high-price || '.'
  }&lt;/category&gt;  
)</eg>
                     <p>The result of the revised query might contain the following element:</p>
                     <eg xml:space="preserve">&lt;category name="Men's Wear"&gt;
  3 products have price greater than 1000.
&lt;/category&gt;</eg>
                  </item>
               </ulist>
               <note>
                  <p>If a collation name is specified, it must be supplied as a literal string; it cannot
                  be computed dynamically. A workaround in such cases is to use
                   the <function>fn:collation-key</function> function. For example:</p>
                  <eg role="parse-test" xml:space="preserve">for $p in $products
group by collation-key($p/description, $collation)
return $product/@code</eg>
                  <p>Note however that the <function>fn:collation-key</function> function might not work
                  for all collations.</p>
               </note>
               <note>
                  <p>Grouping can also be achieved by constructing a map. For example, 
            the function call <code nobreak="false">map:build(//employee, fn { department })</code> constructs a map
            in which employees are grouped by department.</p>
               </note>
            </div3>
            <div3 id="id-order-by-clause" role="xquery">
               <head>Order By Clause</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-OrderByClause">
                     <lhs>OrderByClause</lhs>
                     <rhs>"stable"?  "order"  "by"  (<nt def="prod-xquery40-OrderSpec">OrderSpec<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-OrderByClause-OrderSpec">
                     <lhs>OrderSpec</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OrderModifier">OrderModifier<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-OrderByClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-OrderByClause-OrderModifier">
                     <lhs>OrderModifier</lhs>
                     <rhs>("ascending"  |  "descending")?  ("empty"  ("greatest"  |  "least"))?  ("collation"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-OrderByClause-URILiteral">
                     <lhs>URILiteral</lhs>
                     <rhs>
                        <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-OrderByClause-StringLiteral">
                     <lhs>StringLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>
               </scrap>
               <p>The purpose of an <code nobreak="false">order by</code> clause is to impose a value-based ordering on the tuples in the tuple stream. The output tuple stream of the <code nobreak="false">order by</code> clause contains the same tuples as its input tuple stream, but the tuples may be in a different order.</p>
               <p>For any two tuples <var>T1</var> and <var>T2</var> in the input tuple stream, the relative position
               of <var>T1</var> and <var>T2</var> in the output tuple stream is determined as follows:</p>
               <olist>
                  <item>
                     <p>The two tuples <var>T1</var> and <var>T2</var> are compared using each <nt def="prod-xquery40-OrderSpec">OrderSpec<!--$spec = xquery40--></nt>
               in turn. If an <nt def="prod-xquery40-OrderSpec">OrderSpec<!--$spec = xquery40--></nt> determines that the two tuples are equal, then
               they are compared using the next <nt def="prod-xquery40-OrderSpec">OrderSpec<!--$spec = xquery40--></nt>; the first <nt def="prod-xquery40-OrderSpec">OrderSpec<!--$spec = xquery40--></nt>
               for which they compare not equal determines the final ordering. If the two tuples compare equal under
               every <nt def="prod-xquery40-OrderSpec">OrderSpec<!--$spec = xquery40--></nt> then their final relative position depends on the <code nobreak="false">stable</code>
               specification, as described below.</p>
                  </item>
                  <item>
                     <p>The result of comparing two tuples <var>T1</var> and <var>T2</var> under <nt def="prod-xquery40-OrderSpec">OrderSpec<!--$spec = xquery40--></nt>
                        <var>K</var> is obtained as follows:</p>
                     <olist>
                        <item>
                           <p>The <term>effective empty order</term> of <var>K</var> is <term>empty least</term> if
                           <var>K</var> specifies <code nobreak="false">empty least</code>, <term>empty greatest</term> if <var>K</var>
                           specifies <code nobreak="false">empty greatest</code>, or by default, the <termref def="dt-default-empty-order">default order for empty sequences</termref> in the <termref def="dt-static-context">static context</termref>.
                           </p>
                        </item>
                        <item>
                           <p>The <term>effective collation</term> of <var>K</var> is the collation specified
                           by <var>K</var> if present, or the default collation from the <termref def="dt-static-context">static context</termref> otherwise. If the collation specified
                           by <var>K</var> is a relative URI, that relative URI is  <termref def="dt-resolve-relative-uri">resolved to an absolute URI</termref> using the <termref def="dt-static-base-uri">Static Base URI</termref>. 
                           If an <code nobreak="false">OrderSpec</code> specifies a collation that is not found in <termref def="dt-static-collations">statically known collations</termref>, an error is raised <errorref class="ST" code="0076"/>.
                           </p>
                        </item>
                        <item>
                           <p>The sort key expression (the <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt> within <var>K</var>)
                     is evaluated for both tuples to produce two sort key values <var>V1</var> and <var>V2</var>,
                     using the variable bindings in that tuple.</p>
                           <note>
                              <p>The focus for this evaluation is the focus for the FLWOR expression as a whole. The context
                     item is not changed.</p>
                           </note>
                        </item>
                        <item>
                           <p>
                              <var>V1</var> and <var>V2</var> are <termref def="dt-atomization">atomized</termref> 
                        to produce two atomic sort key values <var>A1</var> and <var>A2</var>.</p>
                        </item>
                        <item>
                           <p>If either <var>A1</var> or <var>A2</var> is a sequence containing more than one item,
                        a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                        </item>
                        <item>
                           <p>Let <var>P</var> be:</p>
                           <olist>
                              <item>
                                 <p>If <var>A1</var> and <var>A2</var> are both empty, then 0.</p>
                              </item>
                              <item>
                                 <p>If <var>A1</var> is empty and <var>A2</var> is not, then -1 if
                              the <term>effective empty order</term> is <term>empty least</term>, otherwise +1.</p>
                              </item>
                              <item>
                                 <p>If <var>A2</var> is empty and <var>A1</var> is not, then +1 if
                              the <term>effective empty order</term> is <term>empty least</term>, otherwise -1.</p>
                              </item>
                              <item>
                                 <p>Otherwise, the result of <code nobreak="false">fn:compare(<var>A1</var>, <var>A2</var>, <var>C</var>)</code>,
                              where <var>C</var> is the <term>effective collation</term> of <var>K</var>.</p>
                              </item>
                              <item>
                                 <p>If <var>A1</var> and <var>A2</var> are not comparable (that is, if
                              <function>fn:compare</function> raises an error when applied to these two values), then 
                              a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                              </item>
                           </olist>
                        </item>
                        <item>
                           <p>Let <var>Q</var>
                        be minus <var>P</var> if <code nobreak="false">descending</code> is specified, or <var>P</var>
                        otherwise.</p>
                        </item>
                        <item>
                           <p>Then <var>T1</var> precedes <var>T2</var> in the result if <var>Q</var> is negative;
                        <var>T1</var> follows <var>T2</var> in the result if <var>Q</var> is positive; while if <var>Q</var>
                        is zero, the process continues to consider the next <nt def="prod-xquery40-OrderSpec">OrderSpec<!--$spec = xquery40--></nt>.</p>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>If <var>T1</var> and <var>T2</var> are equal under all <nt def="prod-xquery40-OrderSpec">OrderSpecs<!--$spec = xquery40--></nt>,
                     the outcome depends on whether <code nobreak="false">stable</code> is specified:</p>
                     <olist>
                        <item>
                           <p>If <code nobreak="false">stable</code> is specified, the original order of <var>T1</var> and <var>T2</var> 
                               is preserved in the output tuple stream.</p>
                        </item>
                        <item>
                           <p>If <code nobreak="false">stable</code> is not specified, the order of <var>T1</var> and <var>T2</var> 
                              in the output tuple stream is <termref def="dt-implementation-dependent">implementation-dependent</termref>.</p>
                        </item>
                     </olist>
                  </item>
               </olist>
               <p>Examples:</p>
               <ulist>
                  <item>
                     <p>This example illustrates the effect of an <code nobreak="false">order by</code> clause on a tuple stream. The keyword <code nobreak="false">stable</code> indicates that, when two tuples have equal sort keys, their order in the input tuple stream is preserved.</p>
                     <p>Input tuple stream:</p>
                     <eg xml:space="preserve">($license = "PFQ519", $make = "Ford",  $value = 16500)
($license = "HAJ865", $make = "Honda", $value = 22750)
($license = "NKV473", $make = "Ford",  $value = 21650)
($license = "RCM922", $make = "Dodge", $value = 11400)
($license = "ZBX240", $make = "Ford",  $value = 16500)
($license = "KLM030", $make = "Dodge", $value = ())</eg>
                     <p>
                        <code nobreak="false">order by</code> clause:</p>
                     <eg xml:space="preserve">stable order by $make,
  $value descending empty least</eg>
                     <p>Output tuple stream:</p>
                     <eg xml:space="preserve">($license = "RCM922", $make = "Dodge", $value = 11400)
($license = "KLM030", $make = "Dodge", $value = ())
($license = "NKV473", $make = "Ford",  $value = 21650)
($license = "PFQ519", $make = "Ford",  $value = 16500)
($license = "ZBX240", $make = "Ford",  $value = 16500)
($license = "HAJ865", $make = "Honda", $value = 22750)</eg>
                  </item>
                  <item>
                     <p>The following example shows how an <code nobreak="false">order by</code> clause can be used to sort the result of a query, even if the sort key is not included in the query result. This query returns employee names in descending order by salary, without returning the actual salaries:</p>
                     <eg role="parse-test" xml:space="preserve">for $e in $employees
order by $e/salary descending
return $e/name</eg>
                  </item>
               </ulist>
               <note>
                  <p>If a collation name is specified, it must be supplied as a literal string; it cannot
                  be computed dynamically. Two possible workarounds are to use the <function>fn:sort-by</function> function
               or the <function>fn:collation-key</function> function.</p>
                  <p>Using <function>fn:sort</function> the expression</p>
                  <eg role="parse-test" xml:space="preserve">for $b in $books/book[price &lt; 100]
order by $b/title
return $b</eg>
                  <p>can be replaced with the following, which uses a dynamically-chosen collation:</p>
                  <eg role="parse-test" xml:space="preserve">
sort-by(
  $books/book[price &lt; 100],
  {'key': function($book) { $book/title },
   'collation': $collation
  }
)
</eg>
                  <p>Alternatively, it is possible to compute collation keys using a dynamically-chosen
               collation, and sort on the values of the collation keys:</p>
                  <eg role="parse-test" xml:space="preserve">for $b in $books/book[price &lt; 100]
order by collation-key($b/title, $collation)
return $b</eg>
                  <p>Note however that the <function>fn:collation-key</function> function might not work
               for all collations.</p>
               </note>
            </div3>
            <div3 id="id-return-clause" role="xquery">
               <head>Return Clause</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-ReturnClause">
                     <lhs>ReturnClause</lhs>
                     <rhs>"return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-ReturnClause-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </scrap>
               <p>The <code nobreak="false">return</code> clause is the final clause of a FLWOR expression. 
               The <code nobreak="false">return</code> clause is evaluated once for each tuple in its input tuple stream,  
               using the variable bindings in the respective tuples, in the order in which these 
               tuples appear in the input tuple stream. The result of the FLWOR
               expression is the <termref def="dt-sequence-concatenation"/> of the results
               of these evaluations.</p>
               <p>The following example illustrates a FLWOR expression containing several clauses. The <code nobreak="false">for</code> clause iterates over all the departments in an input document named <code nobreak="false">depts.xml</code>, binding the variable <code nobreak="false">$d</code> to each department  in turn. For each binding of <code nobreak="false">$d</code>, the <code nobreak="false">let</code> clause binds variable <code nobreak="false">$e</code> to all the employees in the given department, selected from another input document named <code nobreak="false">emps.xml</code> (the relationship between employees and departments is represented by matching their <code nobreak="false">deptno</code> values). Each tuple in the resulting tuple stream contains a pair of bindings for <code nobreak="false">$d</code> and <code nobreak="false">$e</code> (<code nobreak="false">$d</code> is bound to a department and <code nobreak="false">$e</code> is bound to a set of employees in that department). The <code nobreak="false">where</code> clause filters the tuple stream, retaining only those tuples that represent departments having at least ten employees. The <code nobreak="false">order by</code> clause orders the surviving tuples in descending order by the average salary of the employees in the department. The <code nobreak="false">return</code> clause constructs a new <code nobreak="false">big-dept</code> element for each surviving tuple, containing the department number, headcount, and average salary.</p>
               <eg role="parse-test" xml:space="preserve">for $d in doc("depts.xml")//dept
let $e := doc("emps.xml")//emp[deptno eq $d/deptno]
where count($e) &gt;= 10
order by avg($e/salary) descending
return &lt;big-dept&gt;{
  $d/deptno,
  &lt;headcount&gt;{ count($e) }&lt;/headcount&gt;,
  &lt;avgsal&gt;{ avg($e/salary) }&lt;/avgsal&gt;
}&lt;/big-dept&gt;</eg>
               <notes>
                  <ulist>
                     <item>
                        <p>The order in which items appear in the result of a FLWOR expression depends
                        on the ordering of the input tuple stream to the <code nobreak="false">return</code> clause, 
                        which in turn is influenced by <code nobreak="false">order by</code> clauses. For example, 
                        consider the following query, which is based on the same two input documents as the previous example:</p>
                        <eg role="parse-test" xml:space="preserve">for $d in doc("depts.xml")//dept
order by $d/deptno
for $e in doc("emps.xml")//emp[deptno eq $d/deptno]
return &lt;assignment&gt;{
  $d/deptno, $e/name
}&lt;/assignment&gt;</eg>
                        <p>The result of this query is a sequence of <code nobreak="false">assignment</code> elements, 
                        each containing a <code nobreak="false">deptno</code> element and a <code nobreak="false">name</code> element. 
                        The sequence will be ordered primarily by the <code nobreak="false">deptno</code> values because 
                        of the <code nobreak="false">order by</code> clause. 
                        Subsequences of <code nobreak="false">assignment</code> elements with equal <code nobreak="false">deptno</code> 
                        values will be ordered by the document order of their <code nobreak="false">name</code> elements 
                        within the <code nobreak="false">emps.xml</code> document.</p>
                     </item>
                     <item>
                        <p>Parentheses are helpful in <code nobreak="false">return</code> clauses that contain comma operators,
since FLWOR expressions have a higher precedence than the comma
operator. For example, the following query raises an error because
after the comma, <code nobreak="false">$j</code> is no longer within the FLWOR expression, and is an
undefined variable:</p>
                        <eg role="parse-test" xml:space="preserve">let $i := 5
let $j := 20 * $i
return $i, $j</eg>
                        <p>Parentheses can be used to bring <code nobreak="false">$j</code> into the <code nobreak="false">return</code> clause of the FLWOR expression, as the
programmer probably intended:</p>
                        <eg role="parse-test" xml:space="preserve">let $i := 5
let $j := 20 * $i
return ($i, $j)</eg>
                     </item>
                  </ulist>
               </notes>
            </div3>
         </div2>
         <div2 id="id-maps-and-arrays">
            <head>Maps and Arrays</head>
            <p>Most modern programming languages have support for collections of
key/value pairs, which may be called maps, dictionaries, associative
arrays, hash tables, keyed lists, or objects (these are not the same
thing as objects in object-oriented systems). In XQuery 4.0, we call
these maps. Most modern programming languages also support ordered
lists of values, which may be called arrays, vectors, or sequences.
In XQuery 4.0, we have both
sequences and arrays. Unlike sequences, an array is an
item, and can appear as an item in a sequence.</p>
            <p diff="del" at="B">In previous versions of the language, element structures and
sequences were the only complex data structures.  We are adding maps
and arrays to XQuery 4.0 in order to provide lightweight data
structures that are easier to optimize and less complex to use for
intermediate processing and to allow programs to easily combine XML
processing with JSON processing.</p>
            <note>
               <p>The XQuery 4.0 specification focuses on syntax provided for maps
  and arrays, especially constructors and lookup.</p>
               <p>Some of the functionality typically needed for maps and
  arrays is provided by functions defined in <xspecref spec="FO40" ref="maps"/>
               and <xspecref spec="FO40" ref="arrays"/>, including functions used to
  read JSON to create maps and arrays, serialize maps and arrays to
  JSON, combine maps to create a new map, remove map entries to create
  a new map, iterate over the keys of a map, convert an array to
  create a sequence, combine arrays to form a new array, and iterate
  over arrays in various ways.</p>
            </note>
            <div3 id="id-maps">
               <head>Maps</head>
               <changes>
                  <change issue="1651" PR="1703" date="2025-01-14">Ordered maps are introduced.</change>
               </changes>
               <p>
                  <termdef term="map" id="dt-map">A <term>map</term> is a function
  that associates a set of keys with values, resulting in a collection
  of key / value pairs.</termdef>
                  <termdef term="entry" id="dt-entry">Each key / value pair in a map
  is called an <term>entry</term>.</termdef>
                  <termdef term="associated value" id="dt-associated-value">The value
  associated with a given key is called the <term>associated
  value</term> of the key.</termdef>
               </p>
               <p>Maps and their properties are defined in the data model:
               see <xspecref spec="DM40" ref="map-items"/>. For an overview
            of the functions available for processing maps,
            see <xspecref spec="FO40" ref="maps"/>.</p>
               <note>
                  <p>Maps in XQuery 4.0 are ordered.
                  The effect of this property is explained 
                  in <xspecref spec="DM40" ref="map-items"/>. 
                  In an ordered map, the order of entries is predictable
                  and depends on the order in which they were added to the map.</p>
               </note>
               <div4 id="id-map-constructors">
                  <head>Map Constructors</head>
                  <changes>
                     <change issue="1070" PR="1071" date="2024-03-26">
                     In map constructors, the keyword <code nobreak="false">map</code> is now optional, so 
                     <code nobreak="false">map { 0: false(), 1: true() }</code> can now be written <code nobreak="false">{ 0: false(), 1: true() }</code>,
                     provided it is used in a context where this creates no ambiguity.
                  </change>
                     <change issue="1651" PR="1703" date="2025-01-14">The order of key-value
                     pairs in the map constructor is now retained in the constructed map.</change>
                     <change issue="2003" PR="2094" date="2025-07-13">A general expression is allowed within a map
                     constructor; this facilitates the creation of maps in which the
                     presence or absence of particular keys is decided dynamically.</change>
                  </changes>
                  <p>A map can be created using a <nt def="doc-xquery40-MapConstructor">MapConstructor<!--$spec = xquery40--></nt>.</p>
                  <p>Examples are:</p>
                  <eg xml:space="preserve">{ "a": 1, "b": 2 }</eg>
                  <p>which constructs a map with two entries, and</p>
                  <eg xml:space="preserve">{ "a": 1, if ($condition) { map{ "b": 2 } } }</eg>
                  <p>which constructs a map having either one or two entries depending on the
               value of <code nobreak="false">$condition</code>.</p>
                  <p>Both the keys and the values in a map constructor can be supplied as expressions
               rather than as constants.</p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-MapConstructor">
                        <lhs>MapConstructor</lhs>
                        <rhs>"map"?  "{"  (<nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$idref_lang_part = xquery40- --></nt> ** ",")  "}"</rhs>
                     </prod>

                     <prod id="doc-xquery40-MapConstructor-MapConstructorEntry">
                        <lhs>MapConstructorEntry</lhs>
                        <rhs>
                           <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  (":"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                     </prod>

                     <prod id="doc-xquery40-MapConstructor-ExprSingle">
                        <lhs>ExprSingle</lhs>
                        <rhs>
                           <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>
                  </scrap>
                  <note>
                     <p>The keyword <code nobreak="false">map</code> was required in earlier versions
                  of the language; in XQuery 4.0 it becomes optional. There may be cases
                  where using the keyword improves readability.</p>
                     <p>In order to allow the <code nobreak="false">map</code> keyword to be omitted,
                  an incompatible change has been made to XQuery computed element
                  and attribute constructors: if the name of the constructed element
                  or attribute is a language keyword, it must now be written using the
                  <code nobreak="false">QNameLiteral</code> syntax, for example <code nobreak="false">element #div {}</code>.</p>
                     <p>Although the grammar allows a <nt def="doc-xquery40-MapConstructor">MapConstructor<!--$spec = xquery40--></nt>
                  to appear within an <nt def="doc-xquery40-EnclosedExpr">EnclosedExpr<!--$spec = xquery40--></nt> (that is, between
                  curly brackets), this may be confusing to readers, and using the <code nobreak="false">map</code>
                  keyword in such cases may improve clarity. The keyword <code nobreak="false">map</code> is used in the
                  second example above to avoid any confusion between the braces required for the
                  <code nobreak="false">then</code> part of the conditional expression, and the braces
                  required for the inner map constructor.</p>
                     <p>If the <nt def="doc-xquery40-EnclosedExpr">EnclosedExpr<!--$spec = xquery40--></nt>
                  appears in a context such as a <nt def="doc-xquery40-StringTemplate">StringTemplate<!--$spec = xquery40--></nt>,
                  the two adjacent left opening braces must at least be separated by whitespace.</p>
                  </note>
                  <p>When a <nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$spec = xquery40--></nt> is written as two instances of
               <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt> separated by a colon, the first expression
               is evaluated and atomized to form a key, and the second expression is evaluated to form the
               corresponding value. The result is a <xtermref spec="DM40" ref="dt-single-entry-map"/>
               which will be merged into the constructed map, as described below.
               A <termref def="dt-type-error">type error</termref>
                     <errorref class="TY" code="0004"/> occurs if the result of the first
                  expression (after atomization) is not a single atomic item. The result
               of the second expression is used <emph>as is</emph>.</p>
                  <p>When the <nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$spec = xquery40--></nt> is written as a
               single instance of <nt def="doc-xquery40-ExprSingle">ExprSingle<!--$spec = xquery40--></nt> with no colon, it must evaluate
               to a sequence of zero or more map items (<errorref class="TY" code="0004"/>).
                  However, the coercion rules also allow a JNode
                  whose <term>·jvalue·</term> is a map (or a sequence of maps) to be supplied.
                  These map items will be merged into the constructed map, as described below.</p>
                  <p>Each contained <nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$spec = xquery40--></nt> thus
                  delivers zero or more maps, and the result of the map constructor is a new map
                  obtained by merging these component maps, in order, as if by the <function>map:merge</function>
                  function.</p>
                  <p>
                     <termdef id="dt-same-key" term="same key">Two atomic items <var>K1</var> and
    <var>K2</var> have the <term>same key value</term> if
    
    
      <code nobreak="false">fn:atomic-equal(<var>K1</var>, <var>K2</var>)</code> returns <code nobreak="false">true</code>, as specified in <xspecref spec="FO40" ref="func-atomic-equal" diff="chg" at="2023-01-25"/>
                     </termdef>

    If two or more entries have the <termref def="dt-same-key">same key value</termref> then a dynamic
    error is raised <errorref class="DY" code="0137"/>.
                  
                  The error <rfc2119>may</rfc2119> be raised statically if two or more entries can be determined statically
                  to have the <termref def="dt-same-key">same key value</termref>.

    
    </p>
                  <p>The <xtermref spec="DM40" ref="dt-entry-order"/>
                  of the entries in the constructed map retains the order of the 
                  <nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$spec = xquery40--></nt> entries
                  in the input.</p>
                  <example>
                     <head>Constructing a fixed map</head>
                     <p>The following expression constructs a map with seven entries:</p>
                     <eg id="map-weekdays" xml:space="preserve">
{
  "Su" : "Sunday",
  "Mo" : "Monday",
  "Tu" : "Tuesday",
  "We" : "Wednesday",
  "Th" : "Thursday",
  "Fr" : "Friday",
  "Sa" : "Saturday"
}</eg>
                  </example>
                  <example>
                     <head>Constructing a map with conditional entries</head>
                     <p>The following expression constructs a map with either five or seven entries,
                  depending on a supplied condition:</p>
                     <eg xml:space="preserve">
{
  "Mo" : "Monday",
  "Tu" : "Tuesday",
  "We" : "Wednesday",
  "Th" : "Thursday",
  "Fr" : "Friday",
  if ($include-weekends) {
    { "Sa" : "Saturday",
      "Su" : "Sunday"
    }
  }
}</eg>
                     <p>This could also be written:</p>
                     <eg xml:space="preserve">
{
  "Mo" : "Monday",
  "Tu" : "Tuesday",
  "We" : "Wednesday",
  "Th" : "Thursday",
  "Fr" : "Friday",
  { "Sa" : "Saturday",
    "Su" : "Sunday"
  } [$include-weekends]
}</eg>
                  </example>
                  <example>
                     <head>Constructing a map to index nodes</head>
                     <p>The following expression (which uses two nested map constructors)
                  constructs a map that indexes employees by the value 
                  of their <code nobreak="false">@id</code> attribute:</p>
                     <eg xml:space="preserve">{ //employee ! {@id : .} }</eg>
                  </example>
                  <example>
                     <head>Constructing nested maps</head>
                     <p>Maps can nest, and can contain any XDM value. Here is an example of a nested map with values that can be string values, numeric values, or arrays:</p>
                     <eg id="map-book" xml:space="preserve">

{
  "book": {
    "title": "Data on the Web",
    "year": 2000,
    "author": [
      {
        "last": "Abiteboul",
        "first": "Serge"
      },
      {
        "last": "Buneman",
        "first": "Peter"
      },
      {
        "last": "Suciu",
        "first": "Dan"
      }
    ],
    "publisher": "Morgan Kaufmann Publishers",
    "price": 39.95
  }
}
    </eg>
                     <note>
                        <p>The syntax deliberately mimics JSON, but there are a few differences.
               JSON constructs that are not accepted in XQuery 4.0 map
               constructors include the keywords <code nobreak="false">true</code>, <code nobreak="false">false</code>,
               and <code nobreak="false">null</code>, and backslash-escaped characters such as <code nobreak="false">"\n"</code>
               in string literals. In an XQuery 4.0 map constructor, of course, any literal 
               value can be replaced with an expression.</p>
                     </note>
                  </example>
                  <note>
                     <p>
    In some circumstances, it is necessary to include whitespace before or after the colon
    of a <nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$spec = xquery40--></nt> to ensure that it is parsed as intended.
    </p>
                     <p>
    For instance, consider the expression <code nobreak="false">{a:b}</code>.
    Although it matches the EBNF for <nt def="doc-xquery40-MapConstructor">MapConstructor<!--$spec = xquery40--></nt>,
    the “longest terminal” rule (see <specref ref="lexical-structure"/>)
     requires that <code nobreak="false">a:b</code> be parsed as a QName,
    which is likely to result in an error indicating that the prefix <code nobreak="false">a</code>
    has not been declared.
    Changing the expression to <code nobreak="false">{a :b}</code> or <code nobreak="false">{a: b}</code>
    will prevent this, resulting in the intended parse.
    </p>
                     <p>Similarly, consider these three expressions:</p>
                     <eg xml:space="preserve">
{a:b:c}
{a:*:c}
{*:b:c}</eg>
                     <p>
    In each case, the expression matches the EBNF in two different ways,
    but the “longest possible match” rule forces the parse in which
    the first subexpression is <code nobreak="false">a:b</code>, <code nobreak="false">a:*</code>, or <code nobreak="false">*:b</code> (respectively)
    and the second subexpression is <code nobreak="false">c</code>.
    To achieve the alternative parse
    (in which the first expression is merely <code nobreak="false">a</code> or <code nobreak="false">*</code>),
    insert whitespace before and/or after the first colon.
    </p>
                     <p>See <specref ref="lexical-structure"/>.</p>
                  </note>
                  <note>
                     <p>There are also several functions that can be used to construct maps with a variable
               number of entries:</p>
                     <ulist>
                        <item>
                           <p>
                              <function>map:build</function> takes any sequence as input, and for each
                  item in the sequence, it computes a key and a value, by calling user-supplied functions.</p>
                        </item>
                        <item>
                           <p>
                              <function>map:merge</function> takes a sequence of maps (often but not necessarily
                  <xtermref spec="DM40" ref="dt-single-entry-map"/>) and merges them into a single map.</p>
                        </item>
                        <!--<item><p><function>map:of-pairs</function> takes a sequence of 
                     <xtermref spec="FO40" ref="dt-key-value-pair-map">key-value pair maps</xtermref>
                     and merges them into a single map.</p></item>-->
                     </ulist>
                     <p>Either of these functions can be used to build an index of employee
                  elements using the value of the <code nobreak="false">@id</code> attribute as a key:</p>
                     <ulist>
                        <item>
                           <p>
                              <code nobreak="false">map:build(//employee, fn { @id })</code>
                           </p>
                        </item>
                        <item>
                           <p>
                              <code nobreak="false">map:merge(//employee ! { @id, . })</code>
                           </p>
                        </item>
                        <!--<item><p><code>map:of-pairs(//employee ! { 'key': @id, 'value': . })</code></p></item>-->
                     </ulist>
                     <p>Both functions also provide control over:</p>
                     <ulist>
                        <item>
                           <p>The way in which duplicate keys are handled, and </p>
                        </item>
                        <item>
                           <p>The ordering of entries in the resulting map.</p>
                        </item>
                     </ulist>
                  </note>
               </div4>
               <div4 id="id-map-lookup">
                  <head>Maps as Functions</head>
                  <p>Maps are <termref def="dt-function-item">function items</termref>, and 
                  a <termref def="dt-dynamic-function-call"/> can be used to look up
    the value associated with a key in a map.

    
    If <code nobreak="false">$map</code> is a map and <code nobreak="false">$key</code> is a key,
    then <code nobreak="false">$map($key)</code> is equivalent to <code nobreak="false">map:get($map, $key)</code>.
    The semantics of such a function call are formally defined in
    <xspecref spec="FO40" ref="func-map-get"/>.
    
    </p>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">$weekdays("Su")</code> returns the <termref def="dt-associated-value">associated value</termref> of the key <code nobreak="false">Su</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$books("Green Eggs and Ham")</code> returns  <termref def="dt-associated-value">associated value</termref>  of the key <code nobreak="false">Green Eggs and Ham</code>.</p>
                     </item>
                  </ulist>
                  <note>
                     <p>XQuery 4.0 also provides an alternate syntax for map and
      array lookup that is more terse, supports wildcards, and allows lookup to
      iterate over a sequence of maps or arrays. See <specref ref="id-lookup"/> for details.</p>
                  </note>
                  <p>Map lookups can be chained.</p>
                  <p>Examples: (These examples assume that <code nobreak="false">$b</code> is bound to the books map from the previous section)</p>
                  <ulist>
                     <item>
                        <p>The expression <code nobreak="false">$b("book")("title")</code> returns the string <code nobreak="false">Data on the Web</code>.</p>
                     </item>
                     <item>
                        <p>The expression <code nobreak="false">$b("book")("author")</code> returns the array of authors.</p>
                     </item>
                     <item>
                        <p>The expression <code nobreak="false">$b("book")("author")(1)("last")</code> returns the string <code nobreak="false">Abiteboul</code>.</p>
                        <p>(This example combines <specref ref="id-array-lookup"/> with map lookups.)</p>
                     </item>
                  </ulist>
               </div4>
            </div3>
            <div3 id="id-arrays">
               <head>Arrays</head>
               <p/>
               <div4 id="id-array-constructors">
                  <head>Array Constructors</head>
                  <p>
                     <termdef id="dt-array" term="array">An <term>array</term> is
      a <termref def="dt-function-item"/> that associates a set of positions, represented as
      positive integer keys, with values.</termdef> The first position
      in an array is associated with the integer 1.
      <termdef id="dt-member" term="member">The values of an array are called
      its <term>members</term>.</termdef>

      In the type hierarchy, array has a distinct type, which is
      derived from function.
      Atomization converts arrays to sequences (see <termref def="dt-atomization">Atomization</termref>).  
      </p>
                  <p>An array is created using an <nt def="doc-xquery40-ArrayConstructor">ArrayConstructor<!--$spec = xquery40--></nt>.</p>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-ArrayConstructor">
                        <lhs>ArrayConstructor</lhs>
                        <rhs>
                           <nt def="prod-xquery40-SquareArrayConstructor">SquareArrayConstructor<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CurlyArrayConstructor">CurlyArrayConstructor<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-ArrayConstructor-SquareArrayConstructor">
                        <lhs>SquareArrayConstructor</lhs>
                        <rhs>"["  (<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ** ",")  "]"</rhs>
                     </prod>

                     <prod id="doc-xquery40-ArrayConstructor-ExprSingle">
                        <lhs>ExprSingle</lhs>
                        <rhs>
                           <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                           <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-ArrayConstructor-CurlyArrayConstructor">
                        <lhs>CurlyArrayConstructor</lhs>
                        <rhs>"array"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-ArrayConstructor-EnclosedExpr">
                        <lhs>EnclosedExpr</lhs>
                        <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                     </prod>
                  </scrap>
                  <p>
      If a member of an array is a
      node, its node identity is preserved.

      

        In both forms of an <nt def="doc-xquery40-ArrayConstructor">ArrayConstructor<!--$spec = xquery40--></nt>, if a member
        expression evaluates to a node, the associated value is the
        node itself, not a new node with the same values.  If the
        member expression evaluates to a map or array, the associated
        value is a new map or array with the same values.

        </p>
                  <p>A <nt def="prod-xquery40-SquareArrayConstructor">SquareArrayConstructor<!--$spec = xquery40--></nt> 
      consists of a comma-delimited set of argument expressions. It returns an array in which each member contains the value of the corresponding argument expression.</p>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">[ 1, 2, 5, 7 ]</code> creates an array with four members: <code nobreak="false">1</code>, <code nobreak="false">2</code>, <code nobreak="false">5</code>, and <code nobreak="false">7</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ (), (27, 17, 0) ]</code> creates an array with two members: <code nobreak="false">()</code> and the sequence <code nobreak="false">(27, 17, 0)</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ $x, local:items(), &lt;tautology&gt;It is what it is.&lt;/tautology&gt; ]</code> creates an array with three members: the value of $x, the result of evaluating the function call, and a tautology element.</p>
                     </item>
                  </ulist>
                  <p>A <nt def="prod-xquery40-CurlyArrayConstructor">CurlyArrayConstructor<!--$spec = xquery40--></nt>
      can use any  expression to create its members.  It
      evaluates its operand expression to obtain a sequence of items
      and creates an array with these items as members.  Unlike a
      SquareArrayConstructor, a comma in a CurlyArrayConstructor is
      the  <termref def="dt-comma-operator">comma operator</termref>, not a delimiter.
      </p>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">array { $x }</code> creates an array with one member for each item in the sequence to which $x is bound.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array { local:items() }</code> creates an array with one member for each item  in the sequence to which <code nobreak="false">local:items()</code> evaluates.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array { 1, 2, 5, 7 }</code> creates an array with four members: <code nobreak="false">1</code>, <code nobreak="false">2</code>, <code nobreak="false">5</code>, and <code nobreak="false">7</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array { (), (27, 17, 0) }</code> creates an array with three members: <code nobreak="false">27</code>, <code nobreak="false">17</code>, and <code nobreak="false">0</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array { $x, local:items(), &lt;tautology&gt;It is what it is.&lt;/tautology&gt; }</code> creates an array with the following members: the items to which <code nobreak="false">$x</code> is bound, followed by the items to which <code nobreak="false">local:items()</code> evaluates, followed by a tautology element.</p>
                     </item>
                  </ulist>
                  <note>
                     <p>XQuery 4.0 does not provide explicit support for sparse arrays. Use integer-valued maps to represent sparse arrays, 
                     for example: <code nobreak="false">{ 27 : -1, 153 : 17 }</code>.</p>
                  </note>
               </div4>
               <div4 id="id-array-lookup">
                  <head>Arrays as Functions</head>
                  <p>Arrays are <termref def="dt-function-item">function items</termref>, 
                  and a <termref def="dt-dynamic-function-call"/> can be used to look up
    the value associated with position in an array.

    

    
    If <code nobreak="false">$array</code> is an array and <code nobreak="false">$index</code> is an integer corresponding to a position in the array,
    then <code nobreak="false">$array($key)</code> is equivalent to <code nobreak="false">array:get($array, $key)</code>.
    The semantics of such a function call are formally defined in
    <xspecref spec="FO40" ref="func-array-get"/>.
    
    </p>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">[ 1, 2, 5, 7 ](4)</code> evaluates to <code nobreak="false">7</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ [ 1, 2, 3 ], [ 4, 5, 6 ] ](2)</code> evaluates to <code nobreak="false">[ 4, 5, 6 ]</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ [ 1, 2, 3 ], [ 4, 5, 6 ] ](2)(2)</code> evaluates to <code nobreak="false">5</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ 'a', 123, &lt;name&gt;Robert Johnson&lt;/name&gt; ](3)</code> evaluates to <code nobreak="false">&lt;name&gt;Robert Johnson&lt;/name&gt;</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array { (), (27, 17, 0) }(1)</code> evaluates to  <code nobreak="false">27</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array { (), (27, 17, 0) }(2)</code> evaluates to  <code nobreak="false">17</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array { "licorice", "ginger" }(20)</code> raises a dynamic error <xerrorref spec="FO40" class="AY" code="0001"/>.</p>
                     </item>
                  </ulist>
                  <note>
                     <p>XQuery 4.0 also provides an alternate syntax for map and
      array lookup that is more terse, supports wildcards, and allows
      lookup to iterate over a sequence of maps or arrays. See
      <specref ref="id-lookup"/> for details.</p>
                  </note>
               </div4>
            </div3>
            <div3 id="id-lookup">
               <head>Lookup Expressions</head>
               <changes>
                  <change issue="1996" PR="2134" date="2025-07-29">
                  The lookup operator <code nobreak="false">?</code> can now be followed by an arbitrary literal,
                  for cases where keys are items other than integers or NCNames.
                  It can also be followed by a variable reference or a context value reference.
               </change>
               </changes>
               <p diff="add" at="2023-11-15">The operator "?", known as the lookup operator,
               returns values found in the operand map or array.</p>
               <div4 id="id-postfix-lookup">
                  <head>Postfix Lookup Expressions</head>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-LookupExpr">
                        <lhs>LookupExpr</lhs>
                        <rhs>
                           <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                           <nt def="prod-xquery40-Lookup">Lookup<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-PostfixExpr">
                        <lhs>PostfixExpr</lhs>
                        <rhs>
                           <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-Lookup">
                        <lhs>Lookup</lhs>
                        <rhs>"?"  <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-KeySpecifier">
                        <lhs>KeySpecifier</lhs>
                        <rhs>
                           <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Literal">Literal<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ContextValueRef">ContextValueRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupWildcard">LookupWildcard<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-Literal">
                        <lhs>Literal</lhs>
                        <rhs>
                           <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-ContextValueRef">
                        <lhs>ContextValueRef</lhs>
                        <rhs>"."</rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-VarRef">
                        <lhs>VarRef</lhs>
                        <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-ParenthesizedExpr">
                        <lhs>ParenthesizedExpr</lhs>
                        <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-LookupExpr-LookupWildcard">
                        <lhs>LookupWildcard</lhs>
                        <rhs>"*"</rhs>
                     </prod>
                  </scrap>
                  <p>A postfix <code nobreak="false">Lookup</code> has two parts: the left hand operand
                  selects maps or arrays to be searched, and
                  the <code nobreak="false">KeySelector</code> defines the search criteria.</p>
                  <p>First a simple example: given an array <code nobreak="false">$array</code> of maps:</p>
                  <eg xml:space="preserve">[ { "John": 3, "Jill": 5}, {"Peter": 8, "Mary": 6} ]</eg>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">$array?1?John</code> returns <code nobreak="false">3</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$array?2?Mary</code> returns <code nobreak="false">6</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$array?*?*</code> returns <code nobreak="false">(3, 5, 8, 6)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$array?2?*</code> returns <code nobreak="false">(8, 6)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">$array?*?Peter</code> returns <code nobreak="false">8</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">'Peter' -&gt; $array?*?.</code> returns <code nobreak="false">8</code>
                        </p>
                     </item>
                  </ulist>
                  <p>The required type of the left-hand operand is a sequence of maps or arrays
                  (specifically, <code nobreak="false">(map(*) | array(*))*</code>), and the <termref def="dt-coercion-rules"/>
                  are applied with this required type: this means that if the supplied value
                  includes JNodes, these will be coerced to maps or arrays
               by extracting the <term>·jvalue·</term> property of the JNode. The lookup
               operation is applied independently to each of these maps or arrays,
               and the final expression result is the <termref def="dt-sequence-concatenation"/>
               of the individual results.</p>
                  <p>The semantics of a postfix lookup expression <code nobreak="false">
                        <var>E</var>?<var>KS</var>
                     </code> are 
                  defined by the following rules:</p>
                  <olist>
                     <item>
                        <p>
                           <var>E</var> is evaluated to produce a value <code nobreak="false">$V</code>.</p>
                     </item>
                     <item>
                        <p>If <code nobreak="false">$V</code> is not a <termref def="dt-singleton"/> 
                     (that is if <code nobreak="false">count($V) ne 1</code>),
                  then the result (by recursive application of these rules) is the value of
                  <code nobreak="false">for $v in $V return $v?<var>KS</var>
                           </code>.</p>
                     </item>
                     <item>
                        <p>If <code nobreak="false">$V</code> is a <termref def="dt-JNode"/> then it is
                  coerced to the required type <code nobreak="false">(map(*)|array(*))</code>: see
                  <termref def="dt-coercion-rules"/>.</p>
                     </item>
                     <item>
                        <p>If <code nobreak="false">$V</code> (after coercion) is a <termref def="dt-singleton"/> array item (that is, 
                     if <code nobreak="false">$V instance of array(*)</code>) then:</p>
                        <olist>
                           <item>
                              <p>If the <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$spec = xquery40--></nt>
                                 <var>KS</var> is either a
                         <code nobreak="false">Literal</code>, a <code nobreak="false">ContextValueRef</code>, a <code nobreak="false">VarRef</code>,
                        or a <code nobreak="false">ParenthesizedExpr</code>,
                        then it is evaluated as an expression to produce a value <code nobreak="false">$K</code>
                        and the result is:</p>
                              <eg xml:space="preserve">data($K) ! array:get($V, .)</eg>
                              <note>
                                 <p>The focus for evaluating the key specifier expression is the 
                              same as the focus for the <code nobreak="false">Lookup</code> expression itself.</p>
                                 <p>The order of items in the result reflects the order of subscripts in
                              <code nobreak="false">$K</code>: <code nobreak="false">[10, 20, 30]?(3, 1)</code> returns <code nobreak="false">(30, 10)</code>.</p>
                                 <p>This rule implies that a type error (<errorref class="TY" code="0004"/>)
                              is raised if an item in the atomized value of <var>$K</var> cannot be coerced 
                              to the type <code nobreak="false">xs:integer</code>.</p>
                                 <p>This rule also implies that a dynamic error (<xerrorref spec="FO40" class="AY" code="0001"/>)
                              is raised if an integer in the atomized value of <var>$K</var> is outside
                              the range 1 to <code nobreak="false">array:size($V)</code>.</p>
                              </note>
                           </item>
                           <item>
                              <p>If the <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$spec = xquery40--></nt>
                                 <var>KS</var> is an <code nobreak="false">NCName</code>
                           then it is evaluated in the same way as if the <code nobreak="false">NCName</code> were written
                           in quotation marks as a <code nobreak="false">StringLiteral</code>: in consequence,
                           the expression raises a type error <errorref class="TY" code="0004"/>.</p>
                           </item>
                           <item>
                              <p>If the <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$spec = xquery40--></nt>
                                 <code nobreak="false">KS</code> is a wildcard
                           (<code nobreak="false">*</code>), 
                           the result is the same as <code nobreak="false">$V?(1 to array:size($V))</code>:</p>
                              <note>
                                 <p>Note that array items are returned in order.</p>
                              </note>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>If <var>$V</var> is a <termref def="dt-singleton"/> 
                     map item (that is, if <code nobreak="false">$V instance of map(*)</code>)
                     then:</p>
                        <olist>
                           <item>
                              <p>If the <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$spec = xquery40--></nt>
                                 <var>KS</var> is either a
                         <code nobreak="false">Literal</code>, a <code nobreak="false">ContextValueRef</code>, a <code nobreak="false">VarRef</code>,
                        or a <code nobreak="false">ParenthesizedExpr</code>,
                        then it is evaluated as an expression to produce a value <code nobreak="false">$K</code>
                        and the result is:</p>
                              <eg xml:space="preserve">data($K) ! map:get($V, .)</eg>
                              <note>
                                 <p>The focus for evaluating the key specifier expression is the 
                                 same as the focus for the <code nobreak="false">Lookup</code> expression itself.</p>
                                 <p>The order of items in the result reflects the order of keys in
                              <code nobreak="false">$K</code>: <code nobreak="false">{'a':10, 'b':20, 'c':30}?('c', 'a')</code> 
                                 returns <code nobreak="false">(30, 10)</code>.</p>
                                 <p>There is no error when <code nobreak="false">$K</code> includes a key that is not
                              present in the map.</p>
                              </note>
                           </item>
                           <item>
                              <p>If the <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$spec = xquery40--></nt>
                                 <var>KS</var> is an <code nobreak="false">NCName</code>, then the result
                              is the same as if it were written in quotes as
                              a <code nobreak="false">StringLiteral</code>: for example <code nobreak="false">$map?name</code>
                           returns the same result as <code nobreak="false">map?"name"</code>.</p>
                           </item>
                           <item>
                              <p>If the <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$spec = xquery40--></nt>
                                 <var>KS</var> is a wildcard (<code nobreak="false">*</code>), 
                              the result is the same as <code nobreak="false">$V?(map:keys($V))</code>.</p>
                              <note>
                                 <p>The order of entries in the result sequence 
                                 reflects the <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>
                                 of the map.</p>
                              </note>
                           </item>
                        </olist>
                     </item>
                     <item>
                        <p>Otherwise (that is, if <code nobreak="false">$V</code> is neither a map nor an array)
                     a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                     </item>
                  </olist>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">[ 1, 2, 5, 7 ]?*</code> evaluates to <code nobreak="false">(1, 2, 5, 7)</code>.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]?*</code> evaluates to <code nobreak="false">([ 1, 2, 3 ], [ 4, 5, 6 ])</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ [ 1, 2, 3 ], 4, 5 ]?*[. instance of array(xs:integer)]</code> evaluates to <code nobreak="false">([ 1, 2, 3 ])</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ [ 1, 2, 3 ], [ 4, 5, 6 ], 7 ]?*[. instance of array(*)]?2</code> evaluates to <code nobreak="false">(2, 5)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">[ [ 1, 2, 3 ], 4, 5 ]?*[. instance of xs:integer]</code> 
                        evaluates to <code nobreak="false">(4, 5)</code>.
                     </p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-unary-lookup">
                  <head>Unary Lookup</head>
                  <scrap headstyle="show">
                     <prod id="doc-xquery40-UnaryLookup">
                        <lhs>UnaryLookup</lhs>
                        <rhs>
                           <nt def="prod-xquery40-Lookup">Lookup<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-UnaryLookup-Lookup">
                        <lhs>Lookup</lhs>
                        <rhs>"?"  <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-UnaryLookup-KeySpecifier">
                        <lhs>KeySpecifier</lhs>
                        <rhs>
                           <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Literal">Literal<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ContextValueRef">ContextValueRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupWildcard">LookupWildcard<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-UnaryLookup-Literal">
                        <lhs>Literal</lhs>
                        <rhs>
                           <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-UnaryLookup-ContextValueRef">
                        <lhs>ContextValueRef</lhs>
                        <rhs>"."</rhs>
                     </prod>

                     <prod id="doc-xquery40-UnaryLookup-VarRef">
                        <lhs>VarRef</lhs>
                        <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        </rhs>
                     </prod>

                     <prod id="doc-xquery40-UnaryLookup-ParenthesizedExpr">
                        <lhs>ParenthesizedExpr</lhs>
                        <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                     </prod>

                     <prod id="doc-xquery40-UnaryLookup-LookupWildcard">
                        <lhs>LookupWildcard</lhs>
                        <rhs>"*"</rhs>
                     </prod>
                  </scrap>
                  <p>Unary lookup is most commonly used in predicates (for example, <code nobreak="false">$map[?name = 'Mike']</code>)
                  or with the simple map operator (for example, <code nobreak="false">avg($maps ! (?price - ?discount))</code>).</p>
                  <p>The unary lookup expression <code nobreak="false">?KS</code> is defined to be equivalent to the postfix lookup
                  expression <code nobreak="false">.?KS</code>, which has the context value (<code nobreak="false">.</code>) as the implicit first operand.
                  See <specref ref="id-postfix-lookup"/> for the postfix lookup operator.</p>
                  <note>
                     <p>Although the grammar allows the key specifier to be a context value expression,
               this is of no practical use with a unary lookup. The expression <code nobreak="false">[1, 2, 3] -&gt; ?.</code> expands to
               <code nobreak="false">[1, 2, 3]?(1, 2, 3)</code> which returns <code nobreak="false">(1, 2, 3)</code>; but a more
               likely result is a type error or array bounds error.</p>
                  </note>
                  <p>Examples:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">?name</code> is equivalent to <code nobreak="false">.("name")</code>, an appropriate lookup for a map.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">?2</code> is equivalent to <code nobreak="false">.(2)</code>, an appropriate lookup for an array or an integer-valued map.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">?"first name"</code> is equivalent to <code nobreak="false">.("first name")</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">?#code</code> is equivalent to <code nobreak="false">.(#code)</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">?($a)</code> and <code nobreak="false">?$a</code> are 
                        equivalent to <code nobreak="false">for $k in $a return .($k)</code>, 
                        allowing keys for an array or map to be passed using a variable.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">?(3e0)</code> and <code nobreak="false">?3e0</code> return the same result as
                        <code nobreak="false">?3</code>, because <code nobreak="false">xs:double(3e0)</code> and
                        <code nobreak="false">xs:integer(3)</code> compare equal under the rules of the
                        <function>atomic-equal</function> function.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">?(2 to 4)</code> is equivalent to <code nobreak="false">for $k in (2, 3, 4) return .($k)</code>, 
                        a convenient way to return a range of values from an array.</p>
                     </item>
                     <item role="xquery">
                        <p>If the context value is an array, <code nobreak="false">let $x:= &lt;node i="3"/&gt; return ?($x/@i)</code> 
                        does not raise a type error, because the attribute is untyped.</p>
                        <p>But <code nobreak="false">let $x:= &lt;node i="3"/&gt; return ?($x/@i+1)</code> does raise a type error
                        because the <code nobreak="false">+</code> operator with an untyped operand returns a double.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">([ 1, 2, 3 ], [ 1, 2, 5 ], [ 1, 2 ])[?3 = 5]</code> raises an error,
                        because <code nobreak="false">?3</code> applied to one of the
                        items in the sequence fails.</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="id-lookup-vs-path-expressions">
                  <head>Comparing Lookup and Path Expressions</head>
                  <p>Lookup expressions are retained in this specification with only
                  minor changes from the previous version 3.1. They remain a convenient
                  solution for simple lookups of entries in maps and arrays.</p>
                  <p>For more complex queries into trees of maps and arrays, XQuery 4.0
                  introduces a generalization of path expressions (see <specref ref="id-path-expressions"/>)
                  which can now handle <termref def="dt-JTree">JTrees</termref> 
                     as well as <termref def="dt-XTree">XTrees</termref>.</p>
                  <p>For simple expressions, the capabilities of the two constructs overlap.
                  For example, if <code nobreak="false">$m</code> is a map, then the expressions
                  <code nobreak="false">$m?code = 3</code> and <code nobreak="false">$m/code = 3</code> have the same effect.
                  Path expressions, however, have more power, and with it, more complexity.
                  The expression <code nobreak="false">$m/code = 3</code> (unless simplified by an optimizer)
                  effectively expands the expression to
                  <code nobreak="false">(jtree($m)/child::get("code") =&gt; jvalue()) = 3</code>:
                  that is, the supplied map is wrapped in a JNode, the child axis returns a sequence of JNodes,
                  and the <term>·jvalue·</term> properties of these JNodes are compared with the
                  supplied value <code nobreak="false">3</code>.</p>
                  <p>Whereas simple lookups of specific entries in maps and arrays work well,
                  experience has shown that the <code nobreak="false">?*</code> wildcard lookup can be problematic.
                  This is because of the flattening effect: for example, given the array
                  <code nobreak="false">let $A := [(1,2), (3,4), (), 5]</code> the result of the expression
                  <code nobreak="false">$A?*</code> is the sequence <code nobreak="false">(1, 2, 3, 4, 5)</code> which loses information
                  that might be needed for further processing. By contrast, the path expression
                  <code nobreak="false">$A/*</code> (or <code nobreak="false">$A/child::*</code>) returns a sequence of four
                  JNodes, whose <term>·jvalue·</term> properties are respectively <code nobreak="false">(1,2)</code>, 
                     <code nobreak="false">(3,4)</code>, <code nobreak="false">()</code>, and <code nobreak="false">5</code>.</p>
                  <p>The result of a lookup expression is a simple value (the value of an entry in a map
                  or a member of an array, or the <termref def="dt-sequence-concatenation"/> of 
                  several such values). By contrast, the result of a path expression applied to maps
                  or arrays is always a sequence of JNodes. These JNodes can be used for further
                  navigation. If only the <term>·jvalue·</term> properties of the JNodes are 
                  needed, these will usually be extracted automatically by virtue of the
                  <termref def="dt-coercion-rules"/>: for example if the value is used in an
                  arithmetic expression or a value comparison, atomization of the JNode
                  automatically extracts its <term>·jvalue·</term>. In other cases the value can
                  be extracted explicitly by a call of the <function>jvalue</function> function.</p>
                  <p>Lookup expressions on arrays result in a dynamic error if the subscript is out
                  of bounds, whereas the equivalent path expression succeeds, returning the empty
                  sequence. For example <code nobreak="false">array{1 to 5}?10</code> raises 
                     <xerrorref spec="FO40" class="AY" code="0001"/>, whereas <code nobreak="false">array{1 to 5}/get(10)</code>
                     returns a empty sequence.
                 </p>
               </div4>
               <div4 id="id-implausible-lookup-expressions" diff="add" at="Issue602">
                  <head>Implausible Lookup Expressions</head>
                  <p>Under certain conditions a lookup expression that will never select anything
                  is classified as <termref def="dt-implausible"/>. During the static analysis
                  phase, a processor <rfc2119>may</rfc2119> (subject to the rules in
                  <specref ref="id-implausible-expressions"/>) report a static error
                  when such lookup expressions are encountered: <errorref class="TY" code="0145"/>.</p>
                  <p>More specifically, a shallow unary or postfix lookup is classified as 
                  <termref def="dt-implausible"/> if any of the following conditions applies:</p>
                  <olist>
                     <item>
                        <p>The inferred type of the left-hand operand (or the context value, in the case
                  of a unary expression) is a record type (see <specref ref="id-record-test"/>),
                  and the <code nobreak="false">KeySpecifier</code> is an <code nobreak="false">IntegerLiteral</code>.
                  </p>
                     </item>
                     <item>
                        <p>The inferred type of the left-hand operand (or the context value, in the case
                     of a unary expression) is a record type (see <specref ref="id-record-test"/>),
                     and the <code nobreak="false">KeySpecifier</code> is an <code nobreak="false">NCName</code> or <code nobreak="false">StringLiteral</code>
                     that cannot validly appear as a field name in the record.
                  </p>
                     </item>
                     <item>
                        <p>The inferred type of the left-hand operand (or the context value, in the case
                     of a unary expression) is a map type,
                     and the inferred type of the <code nobreak="false">KeySpecifier</code>, after coercion, is a type that
                     is disjoint with the key type of the map.
                  </p>
                     </item>
                     <item>
                        <p>The inferred type of the left-hand operand (or the context value, in the case
                     of a unary expression) is an array type,
                     and the <code nobreak="false">KeySpecifier</code> is the <code nobreak="false">IntegerLiteral</code>
                           <code nobreak="false">0</code> (zero).
                  </p>
                     </item>
                  </olist>
                  <note>
                     <p>Other errors, such as using an <code nobreak="false">NCName</code>
                        <code nobreak="false">KeySpecifier</code>
               for an array lookup, are handled under the general provisions for type errors.</p>
                  </note>
                  <p>Examples of implausible lookup expressions include the following:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">parse-uri($uri)?3</code>: the declared result type of <code nobreak="false">parse-uri</code> is a record
                  test, so the selector <code nobreak="false">3</code> will never select anything.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">in-scope-namespaces($node)(current-date())</code>: the result type of
                  <code nobreak="false">in-scope-namespaces</code> is a map with <code nobreak="false">xs:string</code> keys, so the selector
                  <code nobreak="false">current-date()</code> will never select anything.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">array:subarray($a, 2, 5)?0</code>: the integer zero cannot select any member
                  of an array, because numbering starts at 1.</p>
                     </item>
                  </ulist>
               </div4>
            </div3>
            <div3 id="id-methods">
               <head>Method Calls</head>
               <changes>
                  <change issue="2143" date="2025-08-04">A method call invokes a function
                     held as the value of an entry in a map, supplying the map implicitly
                     as the value of the first argument.</change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-MethodCall">
                     <lhs>MethodCall</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  "=?&gt;"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-MethodCall-PostfixExpr">
                     <lhs>PostfixExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-MethodCall-PositionalArgumentList">
                     <lhs>PositionalArgumentList</lhs>
                     <rhs>"("  <nt def="prod-xquery40-PositionalArguments">PositionalArguments<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-MethodCall-PositionalArguments">
                     <lhs>PositionalArguments</lhs>
                     <rhs>(<nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-MethodCall-Argument">
                     <lhs>Argument</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholder<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-MethodCall-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-MethodCall-ArgumentPlaceholder">
                     <lhs>ArgumentPlaceholder</lhs>
                     <rhs>"?"</rhs>
                  </prod>
               </scrap>
               <p>A method call combines accessing a map <var>M</var> to look up an entry
               whose value is a function item <var>F</var>, and calling the function item <var>F</var>
               supplying the map <var>M</var> as the implicit value of the first argument.</p>
               <p>For example, given the variable:</p>
               <eg xml:space="preserve">
let $rectangle := {
  'height':    3,
  'width':     4,
  'area':      fn ($rect) { 
                  $rect?height × $rect?width 
               },
  'perimeter': fn ($rect) { 
                 2 × ($rect?height + $rect?width) 
               },
  'resize':    fn ($rect, $factor) { 
                  $rect 
                     =&gt; map:put('height', $rect?height × $factor)
                     =&gt; map:put('width', $rect?width × $factor)
               }
}
               </eg>
               <p>The method call <code nobreak="false">$rectangle =?&gt; area()</code> returns <code nobreak="false">12</code>, while
               the method call <code nobreak="false">$rectangle =?&gt; perimeter()</code> returns <code nobreak="false">14</code>,
                  and <code nobreak="false">$rectangle =?&gt; resize(2)</code> returns a map representing
               a rectangle with <code nobreak="false">height = 6</code> and <code nobreak="false">width = 8</code>.</p>
               <p>An arity-one function can also be written as a <termref def="dt-focus-function"/>:</p>
               <eg xml:space="preserve">
let $rectangle := {
  'height': 3,
  'width': 4,
  'area': fn { ?height × ?width }
}
               </eg>
               <p>The expression <code nobreak="false">
                     <var>M</var> =?&gt; <var>N</var>(<var>X</var>, <var>Y</var>, ...)</code>
                  is by definition equivalent to:</p>
               <eg xml:space="preserve">for $map as map(*) in <var>M</var>
let $f as function(*) := $map?<var>N</var>                 
return $f($map, <var>X</var>, <var>Y</var>, ...)</eg>
               <p>(where <code nobreak="false">$map</code> and <code nobreak="false">$f</code>
                  are otherwise unused variable names).</p>
               <note>
                  <p>The left-hand operand can be a sequence of maps. For example, given <code nobreak="false">$rectangle</code>
              defined as in the first example above, the expression <code nobreak="false">((1 to 2) ! $rectangle =?&gt; resize(.)) =?&gt; area()</code>
              returns the sequence <code nobreak="false">(12, 48)</code>.</p>
               </note>
               <p>The argument list in a method call must not include an argument placeholder; that is,
               the call must not be a partial function application (<errorref class="ST" code="0003"/>).</p>
               <note>
                  <p>Implicit in this definition are the following rules:</p>
                  <ulist>
                     <item>
                        <p>The value of <var>M</var> must be
                     a sequence of zero or more maps;</p>
                     </item>
                     <item>
                        <p>Each of those maps must have an entry with the
                        key <var>N</var> (as an instance of <code nobreak="false">xs:string</code>,
                        <code nobreak="false">xs:untypedAtomic</code>, or <code nobreak="false">xs:anyURI</code>);</p>
                     </item>
                     <item>
                        <p>The value of that entry must be
                     a single function item;</p>
                     </item>
                     <item>
                        <p>That function item must have an arity equal to one plus the number
                        of supplied arguments, and the signature of the function
                        must allow a map to be supplied as the first argument.</p>
                     </item>
                  </ulist>
                  <p>The error codes raised if these conditions are not satisfied are
                  exactly the same as if the expanded code were used directly.</p>
               </note>
               <note>
                  <p>Although methods mimic some of the capability of object-oriented
                  languages, the functionality is more limited:</p>
                  <ulist>
                     <item>
                        <p>There is no encapsulation: the entries in a map are all publicly
                     exposed.</p>
                     </item>
                     <item>
                        <p>There is no class hierarchy, and no inheritance or overriding.</p>
                     </item>
                     <item>
                        <p>Methods within a map can be removed or replaced in the same way as
                     any other entries in the map.</p>
                     </item>
                  </ulist>
               </note>
               <note>
                  <p>Methods can be useful when there is a need to write inline recursive
                  functions. For example:</p>
                  <eg xml:space="preserve">
let $lib := {
  'product': fn($map as map(*), $in as xs:double*) {
    if (empty( $in ))
    then 1
    else head($in) × $map =?&gt; product(tail($in))
  }
}
return $lib =?&gt; product((1.2, 1.3, 1.4))
                  </eg>
                  <p>In an environment that supports XPath but not XQuery, this mechanism can be used 
                  to define all the functions that a particular XPath expression needs to invoke,
                  and these functions can be mutually recursive.</p>
               </note>
               <note role="xquery">
                  <p>Methods are often useful in conjunction with named record types:
                  see <specref ref="id-functions-as-fields"/>.</p>
               </note>
               <example>
                  <head>Chaining method calls</head>
                  <p>In the example above, <code nobreak="false">$rectangle =?&gt; area()</code>, <code nobreak="false">$rectangle</code>
               is typically a single map, and <code nobreak="false">area</code> is the key of one of the entries in the map, the value
               of the entry being a function item that takes the map as its implicit first argument. 
               The method call
                  <code nobreak="false">$rectangle =?&gt; area()</code> first performs a map lookup (<code nobreak="false">$rectangle?area</code>)
                  to select the function item, and then calls the function item, supplying the containing
                  map as the first (and in this case only) argument.</p>
                  <p>Such calls can be chained. For example, <code nobreak="false">$rectangle =?&gt; resize(2)</code> returns a rectangle that
               is twice the size of the original, so <code nobreak="false">$rectangle =?&gt; resize(2) =?&gt; area()</code> returns the area of the
               enlarged rectangle.</p>
                  <note>
                     <p>Note how the <code nobreak="false">resize</code> function is implemented using <code nobreak="false">map:put</code>, which
               ensures that the map entries holding function items (<code nobreak="false">area</code>, <code nobreak="false">perimeter</code>, and
               <code nobreak="false">resize</code>, are automatically present and unchanged in the modified map.</p>
                  </note>
                  <p>This kind of chaining extends to the case where a method returns zero or more maps. For example, suppose
               that rectangles are nested, and that <code nobreak="false">$rectangle =?&gt; contents()</code> delivers a sequence of zero or more 
               rectangles. Then the expression <code nobreak="false">$rectangle =?&gt; area() - sum($rectangle =?&gt; contents() =?&gt; area())</code> returns
               the difference between the area of the containing rectangle and the total area of the contained
               rectangles. This works because the dynamic function call <code nobreak="false">$rectangle =?&gt; contents() =?&gt; area()</code>
               applies the <code nobreak="false">area</code> function in each of the maps in the sequence returned
               by the expression <code nobreak="false">$rectangle =?&gt; contents()</code>.</p>
                  <p role="xquery">A record type representing a rectangle containing nested rectangles might be defined
               in XQuery 4.0  like this:</p>
                  <eg role="xquery" xml:space="preserve">
declare record my:rectangle (
   height as xs:double,
   width as xs:double,
   children as my:rectangle* 
     := (),
   area as fn(my:rectangle) as xs:double 
     := fn{?height × ?width},
   resize as fn(my:rectangle, xs:double) as my:rectangle 
     := fn($rect, $factor) {
           $rect =&gt; map:put('height', $rect?height × $factor)
             =&gt; map:put('width', $rect?width × $factor)
             =&gt; map:put('children', $rect?children =?&gt; resize($factor))
        },
   contents as fn(my:rectangle) as my:rectangle*
     := fn{?children}
);
               </eg>
               </example>
            </div3>
            <div3 id="id-filter-maps-and-arrays">
               <head>Filter Expressions for Maps and Arrays</head>
               <changes>
                  <change issue="1159" PR="1163" date="2024-04-20">
                  Filter expressions for maps and arrays are introduced.
               </change>
                  <change issue="1207" PR="1217" date="2024-05-15">
                  Predicates in filter expressions for maps and arrays can now be numeric.
               </change>
                  <change issue="2351">
                  The group is considering removing or substantially changing this feature,
                  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>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-FilterExprAM">
                     <lhs>FilterExprAM</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  "?["  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "]"</rhs>
                  </prod>

                  <prod id="doc-xquery40-FilterExprAM-PostfixExpr">
                     <lhs>PostfixExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-FilterExprAM-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>
               </scrap>
               <p>Maps and arrays can be filtered using the construct <code nobreak="false">
                     <var>INPUT</var>?[<var>FILTER</var>]</code>.
            For example, <code nobreak="false">$array?[count(.)=1]</code> filters an array to retain only those members that 
            are single items.</p>
               <note>
                  <p>The character-pair <code nobreak="false">?[</code> forms a single token; no intervening whitespace
            or comment is allowed.</p>
               </note>
               <p>The required type of the left-hand operand <code nobreak="false">
                     <var>INPUT</var>
                  </code> is
               <code nobreak="false">(map(*)|array(*))?</code>: that is, it must be either the empty sequence, a single
            map, or a single array <errorref class="TY" code="0004"/>. 
               However, the coercion rules also allow a JNode
                  whose <term>·jvalue·</term> is a map or array to be supplied.
               If the value is the empty sequence, 
               the result of the expression is the empty sequence.</p>
               <p>If the value of <code nobreak="false">
                     <var>INPUT</var>
                  </code> is an array, then the 
               <code nobreak="false">
                     <var>FILTER</var>
                  </code> expression is evaluated
            for each member of the array, with that member as the context value, with its position in the
            array as the context position, and with the size of the array as the context size. The result
            of the expression is an array containing those members of the input array for which
               the <termref def="dt-predicate-truth-value"/> of the 
               <code nobreak="false">
                     <var>FILTER</var>
                  </code> expression is true. The order
            of retained members is preserved.</p>
               <p>For example, the following expression:</p>
               <eg xml:space="preserve">let $array := [ (), 1, (2, 3), (4, 5, 6) ]
return $array?[count(.) ge 2]</eg>
               <p>returns:</p>
               <eg xml:space="preserve">[ (2, 3), (4, 5, 6) ]</eg>
               <note>
                  <p>Numeric predicates are handled in the same way as with filter expressions for 
               sequences. However, the result is always an array, even if only one member
            is selected. For example, given the <code nobreak="false">$array</code> shown above, the result
            of <code nobreak="false">$array?[3]</code> is the <xtermref spec="DM40" ref="dt-single-member-array"/>
                     <code nobreak="false">[ (2, 3) ]</code>.
            Contrast this with <code nobreak="false">$array?3</code> which delivers the sequence <code nobreak="false">2, 3</code>.</p>
               </note>
               <p>If the value of <code nobreak="false">
                     <var>INPUT</var>
                  </code> is a map, then the 
               <code nobreak="false">
                     <var>FILTER</var>
                  </code> expression is evaluated
               for each entry in the map, with the context value set to an item of type
               <code nobreak="false">record(key as xs:anyAtomicType, value as item()*)</code>, in which the <code nobreak="false">key</code>
               and <code nobreak="false">value</code> fields represent the key and value of the map entry. 
               The context position is the position of the entry in the map 
               (in <xtermref spec="DM40" ref="dt-entry-order"/>),
               and the context size is the number of entries in the map. The result
               of the expression is a map containing those entries of the input map for which
               the <termref def="dt-predicate-truth-value"/> of the <code nobreak="false">
                     <var>FILTER</var>
                  </code> expression is true.
               The relative order of entries in the result retains the relative order of entries in the input.
            </p>
               <p>For example, the following expression:</p>
               <eg xml:space="preserve">let $map := { 1: "alpha", 2: "beta", 3: "gamma" }
return $map?[?key ge 2]</eg>
               <p>returns:</p>
               <eg xml:space="preserve">{ 2: "beta", 3: "gamma" }</eg>
               <note>
                  <p>A filter expression such as <code nobreak="false">$map?[last()-1, last()]</code>
                  might be used to return the last two entries of a map in
                  <xtermref spec="DM40" ref="dt-entry-order"/>.</p>
               </note>
            </div3>
         </div2>
         <div2 role="xquery" id="id-unordered-expressions">
            <head>Ordered and Unordered Expressions</head>
            <changes>
               <change issue="1339" PR="1342" date="2024-09-03">
               The <code nobreak="false">ordered { E }</code> and <code nobreak="false">unordered { E }</code> expressions are retained for
               backwards compatibility reasons, but in XQuery 4.0 they are deprecated and have no useful effect.
            </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-OrderedExpr">
                  <lhs>OrderedExpr</lhs>
                  <rhs>"ordered"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-OrderedExpr-EnclosedExpr">
                  <lhs>EnclosedExpr</lhs>
                  <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>
            </scrap>
            <p>This syntax is retained from earlier versions of XQuery; in XQuery 4.0 it is deprecated and has
         no effect.</p>
            <p>The constructs <code nobreak="false">ordered { E }</code> and <code nobreak="false">unordered { E }</code> both return the result
         of evaluating the expression <code nobreak="false">E</code>.</p>
            <note>
               <p>In addition to <code nobreak="false">ordered</code> and <code nobreak="false">unordered</code> expressions, 
            XQuery provides a function named <function>fn:unordered</function> that operates on any sequence 
            of items and returns the same sequence in an <termref def="dt-implementation-defined">implementation-defined</termref> order. A call to the <function>fn:unordered</function> 
            function may be thought of as giving permission for the argument expression to be 
            materialized in whatever order the system finds most efficient. The <function>fn:unordered</function> 
            function relaxes ordering only for the sequence that is its immediate operand, whereas the <code nobreak="false">unordered</code> 
            expression in earlier XQuery versions sets the ordering mode for its operand expression and 
            all nested expressions.</p>
            </note>
         </div2>
         <div2 id="id-conditionals">
            <head>Conditional Expressions</head>
            <changes>
               <change issue="234" PR="284" date="2023-01-23">
               Alternative syntax for conditional expressions is available: <code nobreak="false">if (condition) { X }</code>.
            </change>
            </changes>
            <p diff="chg" at="2022-12-07">XQuery 4.0 allows conditional expressions to be written in several different ways.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-IfExpr">
                  <lhs>IfExpr</lhs>
                  <rhs>"if"  "("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  ")"  (<nt def="prod-xquery40-UnbracedActions">UnbracedActions<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedAction">BracedAction<!--$idref_lang_part = xquery40- --></nt>)</rhs>
               </prod>

               <prod id="doc-xquery40-IfExpr-Expr">
                  <lhs>Expr</lhs>
                  <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-IfExpr-UnbracedActions">
                  <lhs>UnbracedActions</lhs>
                  <rhs>"then"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  "else"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-IfExpr-ExprSingle">
                  <lhs>ExprSingle</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-IfExpr-BracedAction">
                  <lhs>BracedAction</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-IfExpr-EnclosedExpr">
                  <lhs>EnclosedExpr</lhs>
                  <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>
            </scrap>
            <p>The braced expression <code nobreak="false">if (<var>C</var>) then {<var>T</var>}</code> is equivalent to the
         unbraced expression <code nobreak="false">if (<var>C</var>) then <var>T</var> else ()</code>.</p>
            <p>The value <var>V</var> of a conditional expression in the form <code nobreak="false">if (<var>C</var>) then <var>T</var>
         else <var>E</var>
               </code> is obtained as follows:</p>
            <olist>
               <item>
                  <p>Let <var>B</var> be the <termref def="dt-ebv">effective boolean value</termref> of the test expression
                       <var>C</var>, as defined in <specref ref="id-ebv"/>.</p>
               </item>
               <item>
                  <p>If <var>B</var> is true, <var>V</var> is the
                    result of evaluating <var>T</var>.</p>
               </item>
               <item>
                  <p>Otherwise, <var>V</var> is the
                    result of evaluating <var>E</var>.</p>
               </item>
            </olist>
            <p>Conditional expressions have a special rule for propagating <termref def="dt-dynamic-error">dynamic errors</termref>: <phrase diff="chg" at="2023-01-10">expressions whose value is not needed for
                  computing the result are
            <termref def="dt-guarded"/>, as described in <specref ref="id-guarded-expressions"/>, to prevent
                  spurious dynamic errors.</phrase>
            </p>
            <p>Here are some examples of conditional expressions:</p>
            <ulist>
               <item>
                  <p>In this example, the test expression is a comparison expression:</p>
                  <eg role="parse-test" xml:space="preserve">if ($widget1/unit-cost &lt; $widget2/unit-cost)
then $widget1
else $widget2</eg>
               </item>
               <item>
                  <p>In this example, the test expression tests for the existence of an attribute
named <code nobreak="false">discounted</code>, independently of its value:</p>
                  <eg role="parse-test" xml:space="preserve">if ($part/@discounted)
then $part/wholesale
else $part/retail</eg>
               </item>
               <item diff="add" at="2022-12-07">
                  <p>The following example returns the attribute node <code nobreak="false">@discount</code> provided the value of <code nobreak="false">@price</code>
                  is greater than 100; otherwise it returns the empty sequence:</p>
                  <eg role="parse-test" xml:space="preserve">if (@price gt 100) { @discount }</eg>
               </item>
               <item diff="add" at="2023-01-10">
                  <p>The following example tests a number of conditions:</p>
                  <eg role="parse-test" xml:space="preserve">if (@code = 1) then
  "food"
else if (@code = 2) then
  "fashion"
else if (@code = 3) then
  "household"
else 
  "general"
</eg>
               </item>
            </ulist>
            <note diff="add" at="2023-01-10">
               <p>The “dangling else ambiguity” found in many other languages cannot arise:</p>
               <ulist>
                  <item>
                     <p>In the unbraced format, both the <code nobreak="false">then</code> and <code nobreak="false">else</code> clauses
                  are mandatory.</p>
                  </item>
                  <item>
                     <p>In the braced format, the expression terminates unambiguously with the closing
                  brace.</p>
                  </item>
               </ulist>
            </note>
         </div2>
         <div2 id="id-otherwise" diff="add" at="A">
            <head>Otherwise Expressions</head>
            <changes>
               <change issue="1024" PR="1031" date="2024-02-27">
               An <code nobreak="false">otherwise</code> operator is introduced: <code nobreak="false">A otherwise B</code> returns the
               value of <code nobreak="false">A</code>, unless it is the empty sequence, in which case it returns the value of <code nobreak="false">B</code>.
            </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-OtherwiseExpr">
                  <lhs>OtherwiseExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-StringConcatExpr">StringConcatExpr<!--$idref_lang_part = xquery40- --></nt>  ("otherwise"  <nt def="prod-xquery40-StringConcatExpr">StringConcatExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-OtherwiseExpr-StringConcatExpr">
                  <lhs>StringConcatExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-RangeExpr">RangeExpr<!--$idref_lang_part = xquery40- --></nt>  ("||"  <nt def="prod-xquery40-RangeExpr">RangeExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>
            </scrap>
            <p>The <code nobreak="false">otherwise</code> expression returns the value of its first operand, unless this is the empty
         sequence, in which case it returns the value of its second operand.</p>
            <p>For example, <code nobreak="false">@price - (@discount otherwise 0)</code> returns the value of <code nobreak="false">@price - @discount</code>,
         if the attribute <code nobreak="false">@discount</code> exists, or the value of <code nobreak="false">@price</code> if the <code nobreak="false">@discount</code>
            attribute is absent.</p>
            <p>To prevent spurious errors, the right hand operand is <termref def="dt-guarded"/>: it cannot throw any
            dynamic error unless the left-hand operand returns the empty sequence.</p>
            <note>
               <p>The operator is associative (even under error conditions): <code nobreak="false">A otherwise (B otherwise C)</code> returns
         the same result as <code nobreak="false">(A otherwise B) otherwise C</code>.</p>
               <p>The <code nobreak="false">otherwise</code> operator binds more tightly than comparison operators such as
            <code nobreak="false">=</code>, but less tightly than string concatenation (<code nobreak="false">||</code>) or arithemetic
            operators. The expression <code nobreak="false">$a = @x otherwise @y + 1</code> parses as 
               <code nobreak="false">$a = (@x otherwise (@y + 1))</code>.</p>
            </note>
         </div2>
         <div2 id="id-switch" role="xquery">
            <head>Switch Expressions</head>
            <changes>
               <change issue="328" PR="364" date="2023-03-07">
               Switch expressions now allow a <code nobreak="false">case</code> clause to match multiple atomic items.
            </change>
               <change issue="365" PR="587" date="2023-11-07">
               Switch and typeswitch expressions can now be written with curly brackets,
                  to improve readability.
            </change>
               <change issue="671" PR="678" date="2023-09-12">
               The comparand expression in a switch expression can be omitted, allowing
               the switch cases to be provided as arbitrary boolean expressions.
            </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-SwitchExpr">
                  <lhs>SwitchExpr</lhs>
                  <rhs>"switch"  <nt def="prod-xquery40-SwitchComparand">SwitchComparand<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-SwitchCases">SwitchCases<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedSwitchCases">BracedSwitchCases<!--$idref_lang_part = xquery40- --></nt>)</rhs>
               </prod>

               <prod id="doc-xquery40-SwitchExpr-SwitchComparand">
                  <lhs>SwitchComparand</lhs>
                  <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-SwitchExpr-Expr">
                  <lhs>Expr</lhs>
                  <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-SwitchExpr-SwitchCases">
                  <lhs>SwitchCases</lhs>
                  <rhs>
                     <nt def="prod-xquery40-SwitchCaseClause">SwitchCaseClause<!--$idref_lang_part = xquery40- --></nt>+  "default"  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-SwitchExpr-SwitchCaseClause">
                  <lhs>SwitchCaseClause</lhs>
                  <rhs>("case"  <nt def="prod-xquery40-SwitchCaseOperand">SwitchCaseOperand<!--$idref_lang_part = xquery40- --></nt>)+  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-SwitchExpr-SwitchCaseOperand">
                  <lhs>SwitchCaseOperand</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-SwitchExpr-ExprSingle">
                  <lhs>ExprSingle</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-SwitchExpr-BracedSwitchCases">
                  <lhs>BracedSwitchCases</lhs>
                  <rhs>"{"  <nt def="prod-xquery40-SwitchCases">SwitchCases<!--$idref_lang_part = xquery40- --></nt>  "}"</rhs>
               </prod>
            </scrap>
            <p>
The <term>switch expression</term> chooses one of several expressions to evaluate based on the
input value.
</p>
            <p>
In a <code nobreak="false">switch</code> expression, the <code nobreak="false">switch</code> keyword is followed by an expression enclosed
in parentheses, called the <term>switch comparand</term>. This is the expression whose value is
being compared. <phrase diff="add" at="issue671">This expression is optional, and defaults to <code nobreak="false">true</code>.</phrase>
            The remainder of the <code nobreak="false">switch</code> expression consists of one or more
<code nobreak="false">case</code> clauses, with one or more <code nobreak="false">case operand
expressions</code> each, and a <code nobreak="false">default</code> clause. </p>
            <p>The first step in evaluating a switch expression is to apply
atomization to the value of the switch comparand. <phrase diff="chg" at="2023-02-20">Call the result the <term>switch value</term>.
            If the <term>switch value</term>
               </phrase> is a sequence of length greater than one, a type error is
raised <errorref class="TY" code="0004"/>. In the absence of a switch comparand, the switch value is the
         <code nobreak="false">xs:boolean</code> value <code nobreak="false">true</code>.</p>
            <p>The <phrase diff="chg" at="2023-02-20">
                  <term>switch value</term> is compared to</phrase> 
            each <nt def="prod-xquery40-SwitchCaseOperand">SwitchCaseOperand<!--$spec = xquery40--></nt> in turn until a
            match is found or the list is exhausted. The matching is performed as follows:</p>
            <olist>
               <item>
                  <p>The <nt def="prod-xquery40-SwitchCaseOperand">SwitchCaseOperand<!--$spec = xquery40--></nt> is evaluated.</p>
               </item>
               <item>
                  <p>The resulting value is atomized: call this the <term>case value</term>.</p>
               </item>
               <item>
                  <p diff="chg" at="2023-02-20">If the <term>case value</term> is the empty sequence, then a match occurs if and only if
               the <term>switch value</term> is the empty sequence.</p>
               </item>
               <item>
                  <p>Otherwise, the <termref def="dt-singleton"/>
                     <term>switch value</term> is compared individually
               with each item in the <term>case value</term> in turn, and a match
               occurs if and only if these two atomic items are <xtermref spec="FO40" ref="dt-contextually-equal"/>,
               using the default collation in the static context.</p>
               </item>
            </olist>
            <p>
               <termdef id="id-effective-case-switch-expression" term="effective case"> The <term>effective case</term> of a switch expression is the
first case clause that matches, using the rules given above, or the
default clause if no such case clause exists.</termdef> The value of
the switch expression is the value of the return expression in the
effective case.</p>
            <p>Switch expressions have rules regarding the propagation of dynamic
errors: <phrase diff="chg" at="B">see <specref ref="id-guarded-expressions"/>. These rules mean that</phrase>
the return clauses of a switch expression must not raise any dynamic
errors except in the effective case.  Dynamic errors raised in the
operand expressions of the switch or the case clauses are propagated;
however, an implementation must not raise dynamic errors in the
operand expressions of case clauses that occur after the effective
case. An implementation is permitted to raise dynamic errors in the
operand expressions of case clauses that occur before the effective
case, but not required to do so.</p>
            <p>The following example shows how a switch expression might be used:</p>
            <eg role="parse-test" diff="chg" at="2023-07-01" xml:space="preserve">
switch ($animal) {
  case "Cow" return "Moo"
  case "Cat" return "Meow"
  case "Duck", "Goose" return "Quack"
  default return "What's that odd noise?"
}</eg>
            <p diff="add" at="2023-07-01">The curly brackets in a switch expression are optional. The above example can equally
         be written:</p>
            <eg role="parse-test" xml:space="preserve">
switch ($animal) 
  case "Cow" return "Moo"
  case "Cat" return "Meow"
  case "Duck", "Goose" return "Quack"
  default return "What's that odd noise?"
</eg>
            <p diff="add" at="issue671">The following example illustrates a switch expression where the comparand is defaulted to
            <code nobreak="false">true</code>:</p>
            <eg role="parse-test" diff="add" at="issue671" xml:space="preserve">
switch () {
  case ($a le $b) return "lesser"
  case ($a ge $b) return "greater"
  case ($a eq $b) return "equal"
  default return "not comparable"
}</eg>
            <note diff="add" at="issue671">
               <p>The comparisons are performed using the <function>fn:deep-equal</function>
         function, after atomization. This means that a case expression such as <code nobreak="false">@married</code>
            tests <code nobreak="false">fn:data(@married)</code> rather than <code nobreak="false">fn:boolean(@married)</code>. 
         If the effective boolean value of the expression is wanted,
         this can be achieved with an explicit call of <function>fn:boolean</function>.</p>
            </note>
         </div2>
         <div2 id="id-quantified-expressions">
            <head>Quantified Expressions</head>
            <changes>
               <change issue="1316" PR="1384" date="2024-08-13">
               If a type declaration is present, the supplied values in the input sequence are now
               coerced to the required type. Type declarations are now permitted in XPath as well as XQuery.
            </change>
            </changes>
            <p>Quantified expressions support existential and universal quantification. The
value of a quantified expression is always <code nobreak="false">true</code> or <code nobreak="false">false</code>.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-QuantifiedExpr">
                  <lhs>QuantifiedExpr</lhs>
                  <rhs>("some"  |  "every")  (<nt def="prod-xquery40-QuantifierBinding">QuantifierBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")  "satisfies"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-QuantifiedExpr-QuantifierBinding">
                  <lhs>QuantifierBinding</lhs>
                  <rhs>
                     <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-QuantifiedExpr-VarNameAndType">
                  <lhs>VarNameAndType</lhs>
                  <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
               </prod>

               <prod id="doc-xquery40-QuantifiedExpr-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-QuantifiedExpr-TypeDeclaration">
                  <lhs>TypeDeclaration</lhs>
                  <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-QuantifiedExpr-SequenceType">
                  <lhs>SequenceType</lhs>
                  <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
               </prod>

               <prod id="doc-xquery40-QuantifiedExpr-ExprSingle">
                  <lhs>ExprSingle</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p>A <term>quantified expression</term> begins with
a <term>quantifier</term>, which is the keyword <code nobreak="false">some</code> or <code nobreak="false">every</code>, 
followed by one or more in-clauses that are used to bind variables,
followed by the keyword <code nobreak="false">satisfies</code> and a test expression. Each in-clause associates a variable with an
expression that returns a sequence of items, called the binding sequence for that variable. 
The value of the quantified expression is defined by the following rules:</p>
            <olist>
               <item>
                  <p>If the <nt def="doc-xquery40-QuantifiedExpr">QuantifiedExpr<!--$spec = xquery40--></nt> contains
               more than one <nt def="prod-xquery40-QuantifierBinding">QuantifierBinding<!--$spec = xquery40--></nt>, then it is equivalent
            to the expression obtained by replacing each comma with <code nobreak="false">satisfies some</code> or <code nobreak="false">satisfies every</code>
            respectively. For example, the expression <code nobreak="false">some $x in X, $y in Y satisfies $x = $y</code>
               is equivalent to <code nobreak="false">some $x in X satisfies some $y in Y satisfies $x = $y</code>,
               while the expression <code nobreak="false">every $x in X, $y in Y satisfies $x lt $y</code> is equivalent to
               <code nobreak="false">every $x in X satisfies every $y in Y satisfies $x lt $y</code>
                  </p>
               </item>
               <item>
                  <p>If the quantifier is <code nobreak="false">some</code>, the <nt def="doc-xquery40-QuantifiedExpr">QuantifiedExpr<!--$spec = xquery40--></nt> returns <code nobreak="false">true</code> 
                  if at least one evaluation of the test expression has the <termref def="dt-ebv">effective boolean value</termref>
                     <code nobreak="false">true</code>; otherwise it returns <code nobreak="false">false</code>. In consequence, if the binding sequence is empty, 
                  the result of the <nt def="doc-xquery40-QuantifiedExpr">QuantifiedExpr<!--$spec = xquery40--></nt> is <code nobreak="false">false</code>.</p>
               </item>
               <item>
                  <p>If the quantifier is <code nobreak="false">every</code>, the <nt def="doc-xquery40-QuantifiedExpr">QuantifiedExpr<!--$spec = xquery40--></nt> returns <code nobreak="false">true</code> 
                  if every evaluation of the test expression has the <termref def="dt-ebv">effective boolean value</termref>
                     <code nobreak="false">true</code>; otherwise it returns <code nobreak="false">false</code>. In consequence, if the binding sequence is empty, 
                  the result of the <nt def="doc-xquery40-QuantifiedExpr">QuantifiedExpr<!--$spec = xquery40--></nt> is <code nobreak="false">true</code>.</p>
               </item>
            </olist>
            <p>The scope of a variable bound in a quantified expression comprises all
subexpressions of the quantified expression that appear after the variable binding. The scope does not include the expression to which the variable is bound.
</p>
            <p>Each variable binding may be accompanied by a <term>type declaration</term>, 
            which consists of the keyword <code nobreak="false">as</code> followed by the static type of 
            the variable, declared using the syntax in  <specref ref="id-sequencetype-syntax"/>. 
            The type declaration defines a required type for the
            value. At run-time, the supplied value for the variable is converted to the required type
            by applying the <termref def="dt-coercion-rules"/>. If conversion is not possible,                     
            a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
            <p diff="chg" at="issue845">The order in which test expressions are evaluated 
            for the various items in the binding sequence is <termref def="dt-implementation-dependent">implementation-dependent</termref>. If the quantifier
               is <code nobreak="false">some</code>, an implementation may
               return <code nobreak="false">true</code> as soon as it finds one item for which the test expression has
               an <termref def="dt-ebv">effective boolean value</termref> of <code nobreak="false">true</code>, and it may raise a <termref def="dt-dynamic-error">dynamic error</termref> as soon as it finds one item for
            which the test expression raises an error. Similarly, if the quantifier is <code nobreak="false">every</code>, an 
            implementation may return <code nobreak="false">false</code> as soon as it finds one item for which the test expression has
            an <termref def="dt-ebv">effective boolean value</termref> of <code nobreak="false">false</code>, and it may raise a <termref def="dt-dynamic-error">dynamic error</termref> as soon as it finds one item for
            which the test expression raises an error. As a result of these rules, the
            value of a quantified expression is not deterministic in the presence of
            errors, as illustrated in the examples below.</p>
            <p>Here are some examples of quantified expressions:</p>
            <ulist>
               <item>
                  <p>This expression is <code nobreak="false">true</code> if every <code nobreak="false">part</code> element has a <code nobreak="false">discounted</code> attribute (regardless of the values of these attributes):</p>
                  <eg role="parse-test" xml:space="preserve">every $part in /parts/part satisfies $part/@discounted</eg>
               </item>
               <item>
                  <p>This expression is <code nobreak="false">true</code> if at least
one <code nobreak="false">employee</code> element satisfies the given comparison expression:</p>
                  <eg role="parse-test" xml:space="preserve">some $emp in /emps/employee satisfies $emp/bonus &gt; 0.25 * $emp/salary</eg>
               </item>
               <item>
                  <p>This expression is <code nobreak="false">true</code> if every
                  <code nobreak="false">employee</code> element has at least one <code nobreak="false">salary</code> child with the attribute <code nobreak="false">current="true"</code>:</p>
                  <eg role="parse-test" xml:space="preserve">every $emp in /emps/employee satisfies (
  some $sal in $emp/salary satisfies $sal/@current = 'true'
)</eg>
                  <note diff="add" at="A">
                     <p>Like many quantified expressions, this can be simplified. This example can be written
                  <code nobreak="false">every $emp in /emps/employee satisfies $emp/salary[@current = 'true']</code>, or even
                  more concisely as <code nobreak="false">empty(/emps/employee[not(salary/@current = 'true')]</code>.</p>
                     <p>Another alternative in XQuery 4.0 is to use the higher-order functions <function>fn:some</function> and <function>fn:every</function>.
               This example can be written <code diff="chg" at="2023-04-25" nobreak="false">every(/emps/employee, fn { salary/@current = 'true' })</code>
                     </p>
                  </note>
               </item>
               <item>
                  <p>In the following examples, each quantified expression evaluates its test
expression over nine pairs of items, formed from the Cartesian
product of the sequences <code nobreak="false">(1, 2, 3)</code> and <code nobreak="false">(2, 3, 4)</code>. 
                  The expression beginning with <code nobreak="false">some</code> evaluates to <code nobreak="false">true</code>, 
                  and the expression beginning with <code nobreak="false">every</code> evaluates to <code nobreak="false">false</code>.</p>
                  <eg role="parse-test" xml:space="preserve">some $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4</eg>
                  <eg role="parse-test" xml:space="preserve">every $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4</eg>
               </item>
               <item>
                  <p>This quantified expression may either return  <code nobreak="false">true</code> or raise a <termref def="dt-type-error">type error</termref>, since its test expression returns <code nobreak="false">true</code> for one item
and raises a <termref def="dt-type-error">type error</termref> for another:</p>
                  <eg role="parse-test" xml:space="preserve">some $x in (1, 2, "cat") satisfies $x * 2 = 4</eg>
               </item>
               <item>
                  <p>This quantified expression may either return <code nobreak="false">false</code> or raise a <termref def="dt-type-error">type error</termref>, since its test expression returns <code nobreak="false">false</code> for one item and raises a <termref def="dt-type-error">type error</termref> for another:</p>
                  <eg role="parse-test" xml:space="preserve">every $x in (1, 2, "cat") satisfies $x * 2 = 4</eg>
               </item>
               <item>
                  <p>This quantified expression returns <code nobreak="false">true</code>, because the binding sequence
                  is empty, despite the fact that the condition can never be satisfied:</p>
                  <eg role="parse-test" xml:space="preserve">every $x in () satisfies ($x lt 0 and $x gt 0)</eg>
               </item>
               <item>
                  <p>This quantified expression is <termref def="dt-implausible"/> because
                  it will always fail with a type error except in the case where <code nobreak="false">$input</code>
                  is the empty sequence. If <code nobreak="false">$input</code> contains one or more <code nobreak="false">xs:date</code>
                  values, a processor <rfc2119>must</rfc2119> raise a type error on the grounds that an <code nobreak="false">xs:date</code>
                  cannot be compared to an <code nobreak="false">xs:integer</code>. If <code nobreak="false">$input</code> is empty, the
                  processor <rfc2119>may</rfc2119> (or may not) report this error:</p>
                  <eg role="parse-test" xml:space="preserve">every $x as xs:date in $input satisfies ($x lt 0)</eg>
               </item>
               <item>
                  <p>This quantified expression  contains a <nt def="prod-xquery40-TypeDeclaration">type declaration<!--$spec = xquery40--></nt> that is not satisfied by every item in the  test expression. 
                  The expression may either return <code nobreak="false">true</code> or raise a <termref def="dt-type-error">type error</termref>.</p>
                  <eg role="parse-test" xml:space="preserve">some $x as xs:integer in (1, 2, "cat") satisfies $x * 2 = 4</eg>
               </item>
            </ulist>
         </div2>
         <div2 id="id-try-catch" role="xquery">
            <head>Try/Catch Expressions</head>
            <changes>
               <change issue="32" PR="493" date="2023-05-16">
               A new variable <code nobreak="false">$err:map</code> is available, capturing all error information in one place.
            </change>
               <change issue="689" PR="1470" date="2024-10-01">
                  <code nobreak="false">$err:stack-trace</code> provides information about the current state of execution.
            </change>
               <change issue="501" PR="1914" date="2025-04-04">
               A <code nobreak="false">finally</code> clause can be supplied, which will always be evaluated after the
               expressions of the try/catch clauses.
            </change>
            </changes>
            <p>The try/catch expression provides error handling for dynamic errors
and type errors raised during dynamic evaluation, including errors
raised by the XQuery implementation and errors explicitly raised in a
query using the <code nobreak="false">fn:error()</code> function.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-TryCatchExpr">
                  <lhs>TryCatchExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-TryClause">TryClause<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-CatchClause">CatchClause<!--$idref_lang_part = xquery40- --></nt>+  <nt def="prod-xquery40-FinallyClause">FinallyClause<!--$idref_lang_part = xquery40- --></nt>?)  |  <nt def="prod-xquery40-FinallyClause">FinallyClause<!--$idref_lang_part = xquery40- --></nt>)</rhs>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-TryClause">
                  <lhs>TryClause</lhs>
                  <rhs>"try"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-EnclosedExpr">
                  <lhs>EnclosedExpr</lhs>
                  <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-CatchClause">
                  <lhs>CatchClause</lhs>
                  <rhs>"catch"  <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-NameTestUnion">
                  <lhs>NameTestUnion</lhs>
                  <rhs>(<nt def="prod-xquery40-NameTest">NameTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")</rhs>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-NameTest">
                  <lhs>NameTest</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-Wildcard">
                  <lhs>Wildcard</lhs>
                  <rhs>"*"<br/>|  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":*")<br/>|  ("*:"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>)<br/>|  (<nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  "*")</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-TryCatchExpr-FinallyClause">
                  <lhs>FinallyClause</lhs>
                  <rhs>"finally"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p>A try/catch expression catches <termref def="dt-dynamic-error">dynamic errors</termref> and
                <termref def="dt-type-error">type errors</termref>
                raised by the evaluation of the target expression of
                the <code nobreak="false">try</code>  clause. If the <termref def="dt-content-expression">content expression</termref> of the try clause does not raise a
                dynamic error or a type error, the result of the
                try/catch expression is the result of the content
                expression.</p>
            <p>If the target expression raises a dynamic error or
                a type error, the result of the try/catch expression
                is obtained by evaluating the first <code nobreak="false">catch</code>
                clause that “matches” the error value, as described
                below.  

		If no catch clause “matches” the
		error value, then the try/catch expression raises the
		error that was raised by the target
		expression.

		A <code nobreak="false">catch</code> clause with one or more
                NameTests matches any error whose error code matches
                one of these NameTests. For instance, if the error
                code is <code nobreak="false">err:FOER0000</code>, then it matches a
                <code nobreak="false">catch</code> clause whose ErrorList is
                <code nobreak="false">err:FOER0000 | err:FOER0001</code>. Wildcards
                may be used in NameTests; thus, the error code
                <code nobreak="false">err:FOER0000</code> also matches a
                <code nobreak="false">catch</code> clause whose ErrorList is
                <code nobreak="false">err:*</code> or <code nobreak="false">*:FOER0000</code> or
                <code nobreak="false">*</code>.</p>
            <p>Within the scope of the <code nobreak="false">catch</code> clause, a
            number of variables are implicitly declared, giving
            information about the error that occurred.  These
            variables are initialized as described in the following
            table:</p>
            <table role="medium">
               <thead>
                  <tr>
                     <th align="left" rowspan="1" colspan="1">Variable</th>
                     <th align="left" rowspan="1" colspan="1">Type</th>
                     <th align="left" rowspan="1" colspan="1">Value</th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:code</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">xs:QName</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">The error code</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:description</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">xs:string?</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">A description of the error condition; the empty sequence
                     if no description is available (for example, if the <function>error</function>
                     function was called with one argument).</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:value</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">item()*</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">Value associated with the error. For an error raised by
                        calling the <function>error</function> function, this is the value of the
                        third argument (if supplied).</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:module</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">xs:string?</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">The URI (or system ID) of the module containing the
                        expression where the error occurred, or the empty sequence if the information
                        is not available.</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:line-number</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">xs:integer?</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">The line number within the module
                        where the error occurred, or the empty sequence if the information
                        is not available. The value <rfc2119>may</rfc2119> be approximate.</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:column-number</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">xs:integer?</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">The column number within the module
                        where the error occurred, or the empty sequence if the information
                        is not available. The value <rfc2119>may</rfc2119> be approximate.</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:stack-trace</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">xs:string?</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <termref def="dt-implementation-dependent">Implementation-dependent</termref> information about the current state of
                     execution, or the empty sequence if no stack trace is available.
                     The variable must be bound so that a query can reference it without
                     raising an error.</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:additional</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">item()*</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <termref def="dt-implementation-defined">Implementation-defined</termref>.
                     Allows implementations to provide any additional information that might be useful.
                     The variable must be bound so that a query can reference it without
                     raising an error.</td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">$err:map</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <code nobreak="false">map(*)</code>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">A map with entries for all values that are bound to the variables above.
                        The local names of the variables are assigned as keys.
                        No map entries are created for those values that are empty sequences.
                        The variable can be used to pass on all error information to another
                        function.</td>
                  </tr>
               </tbody>
            </table>
            <p>Try/catch expressions have a special rule for
                propagating dynamic errors. The try/catch expression
                ignores any dynamic errors encountered in catch
                clauses other than the first catch clause that matches
                an error raised by the try clause, and these catch
                clause expressions need not be evaluated.</p>
            <p>Static errors are not caught by the try/catch
                expression.</p>
            <p>If a function call occurs within a <code nobreak="false">try</code> clause,
                errors raised by evaluating the corresponding function are caught by the try/catch
                expression. If a variable reference is used in a <code nobreak="false">try</code>
                clause, errors raised by binding a value to the variable are not
                caught unless the binding expression occurs within the <code nobreak="false">try</code>
                clause.</p>
            <note>
               <p>The presence of a try/catch expression does not
                  prevent an implementation from using a lazy
                  evaluation strategy, nor does it prevent an
                  optimizer performing expression rewrites. However,
                  if the evaluation of an expression inside a
                  try/catch is rewritten or deferred in this way, it
                  must take its try/catch context with it. Similarly,
                  expressions that were written outside the try/catch
                  expression may be evaluated inside the try/catch,
                  but only if they retain their original try/catch
                  behavior. The presence of a try/catch does not
                  change the rules that allow the processor to
                  evaluate expressions in such a way that may avoid
                  the detection of some errors. </p>
            </note>
            <p>If a concluding <code nobreak="false">finally</code> clause exists, its expression will be evaluated
            after the expressions of the <code nobreak="false">try</code> clause and a possibly evaluated
            <code nobreak="false">catch</code> clause. If it raises an error, this error is returned instead of
            a result or an error that resulted from a <code nobreak="false">try</code> or <code nobreak="false">catch</code>
            expression. If it raises no error, it must yield the empty sequence;
            otherwise, a <termref def="dt-type-error">type error</termref>
            is raised <errorref class="TY" code="0153"/>.</p>
            <note>
               <p>A <code nobreak="false">finally</code> clause can be used to ensure that an expression will always be
               evaluated, no matter if the <code nobreak="false">try</code> expression is successful or if it fails.
               For example, <function>fn:message</function> can be called in the <code nobreak="false">finally</code>
               clause to ensure that an expression has been evaluated even if an error is raised.</p>
            </note>
            <note>
               <p>If <code nobreak="false">try</code> and <code nobreak="false">finally</code> clauses are specified,
            <code nobreak="false">catch</code> clauses can be omitted.</p>
            </note>
            <p>Here are some examples of try/catch expressions.</p>
            <ulist>
               <item>
                  <p>A try/catch expression without name tests catches any error:</p>
                  <eg role="parse-test" xml:space="preserve">try {
  $x cast as xs:integer
} catch * {
  0
}</eg>
               </item>
               <item>
                  <p>With the following catch clause, only <code nobreak="false">err:FORG0001</code> is caught:</p>
                  <eg role="parse-test" xml:space="preserve">try {
  $x cast as xs:integer
} catch err:FORG0001 {
  0
}</eg>
               </item>
               <item>
                  <p>This try/catch expression specifies that errors <code nobreak="false">err:FORG0001</code> and <code nobreak="false">err:XPTY0004</code> are caught:</p>
                  <eg role="parse-test" xml:space="preserve">try {
  $x cast as xs:integer
} catch err:FORG0001 | err:XPTY0004 {
  0
}</eg>
                  <note>
                     <p>In some implementations, <code nobreak="false">err:XPTY0004</code> is detected during static
	evaluation; it can only be caught if it is raised during dynamic evaluation.</p>
                  </note>
               </item>
               <item>
                  <p>This try/catch expression shows how to return information about the error using implicitly defined error variables:</p>
                  <eg role="parse-test" xml:space="preserve">try {
  error(#err:FOER0000)
} catch * {
  $err:code, $err:value, " module: ",
  $err:module, "(", $err:line-number, ",", $err:column-number, ")"
}</eg>
               </item>
               <item>
                  <p>Errors raised by using the result of a try/catch expression are not caught, since they are outside the scope of the <code nobreak="false">try</code> expression.</p>
                  <eg role="parse-test" xml:space="preserve">
declare function local:thrice($x as xs:integer) as xs:integer {
  3 * $x
};

local:thrice(try { "oops" } catch * { 3 } )
</eg>
                  <p>In this example, the try block succeeds, returning the string <code nobreak="false">"oops"</code>, which is not a valid argument to the function.</p>
               </item>
               <item>
                  <p>All available information about the error is serialized:</p>
                  <eg role="parse-test" xml:space="preserve">try {
  1 + &lt;empty/&gt;
} catch * {
  serialize($err:map, { 'method': 'adaptive' })
}</eg>
               </item>
               <item>
                  <p>
                     <function>fn:message</function> will always be called, no matter if the division succeeds:</p>
                  <eg role="parse-test" xml:space="preserve">
for $i in 0 to 2
return try {
  1 div $i
} catch err:FOAR0001 {
  'division error'
} finally {
  message('1 was divided by ' || $i)
}</eg>
               </item>
            </ulist>
         </div2>
         <div2 id="id-expressions-on-datatypes">
            <head>Expressions on SequenceTypes</head>
            <p>
The <code nobreak="false">instance
of</code>, <code nobreak="false">cast</code>, <code nobreak="false">castable</code>,
and <code nobreak="false">treat</code> expressions are used to test whether a value
conforms to a given type or to convert it to an instance of a given
type.
</p>
            <div3 id="id-instance-of">
               <head>Instance Of</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-InstanceofExpr">
                     <lhs>InstanceofExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TreatExpr">TreatExpr<!--$idref_lang_part = xquery40- --></nt>  ("instance"  "of"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-InstanceofExpr-TreatExpr">
                     <lhs>TreatExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CastableExpr">CastableExpr<!--$idref_lang_part = xquery40- --></nt>  ("treat"  "as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-InstanceofExpr-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>
               </scrap>
               <p>The boolean
operator <code nobreak="false">instance of</code>
returns <code nobreak="false">true</code> if the value of its first operand matches
the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> in its second
operand, according to the rules for <termref def="dt-sequencetype-matching">SequenceType
matching</termref>; otherwise it returns <code nobreak="false">false</code>. For example:</p>
               <ulist>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">5 instance of xs:integer</code>
                     </p>
                     <p>This example returns <code nobreak="false">true</code> because the given value is an instance of the given type.</p>
                  </item>
                  <item>
                     <p>
                        <code nobreak="false">5 instance of xs:decimal</code>
                     </p>
                     <p>This example returns <code nobreak="false">true</code> because the given value is an integer literal, and <code nobreak="false">xs:integer</code> is derived by restriction from <code nobreak="false">xs:decimal</code>.</p>
                  </item>
                  <item role="xquery">
                     <p>
                        <code role="parse-test" nobreak="false">&lt;a&gt;{ 5 }&lt;/a&gt; instance of xs:integer</code>
                     </p>
                     <p>This example returns <code nobreak="false">false</code> because the given value is an element rather than an integer.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">(5, 6) instance of xs:integer+</code>
                     </p>
                     <p>This example returns <code nobreak="false">true</code> because the given sequence contains two integers, and is a valid instance of the specified type.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">. instance of element()</code>
                     </p>
                     <p>This example returns <code nobreak="false">true</code> if the context value is a
                     single element node or <code nobreak="false">false</code> if the context value is defined 
                     but is not a single element node. If the context value is <xtermref spec="DM40" ref="dt-absent"/>, a <termref def="dt-type-error"/>
                        is raised <errorref class="DY" code="0002"/>.</p>
                  </item>
               </ulist>
               <note>
                  <p>An <code nobreak="false">instance of</code> test does not allow any kind of casting or coercion.
            The results may therefore be counterintuitive. For example, the expression
            <code nobreak="false">3 instance of xs:positiveInteger</code> returns <code nobreak="false">false</code>, because
            the expression <code nobreak="false">3</code> evaluates to an instance of <code nobreak="false">xs:integer</code>,
            not <code nobreak="false">xs:positiveInteger</code>. For similar reasons, <code nobreak="false">"red" instance of
            enum("red", "green", "blue")</code> returns false.</p>
                  <p>On such occasions, a <code nobreak="false">castable as</code> test may be more appropriate:
            see <specref ref="id-castable"/>
                  </p>
               </note>
            </div3>
            <div3 id="id-typeswitch" role="xquery">
               <head>Typeswitch</head>
               <changes>
                  <change issue="365" PR="587" date="2023-11-07">
                  Switch and typeswitch expressions can now be written with curly brackets,
                  to improve readability.
               </change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-TypeswitchExpr">
                     <lhs>TypeswitchExpr</lhs>
                     <rhs>"typeswitch"  "("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  ")"  (<nt def="prod-xquery40-TypeswitchCases">TypeswitchCases<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedTypeswitchCases">BracedTypeswitchCases<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-TypeswitchCases">
                     <lhs>TypeswitchCases</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CaseClause">CaseClause<!--$idref_lang_part = xquery40- --></nt>+  "default"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>?  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-CaseClause">
                     <lhs>CaseClause</lhs>
                     <rhs>"case"  (<nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>  "as")?  <nt def="prod-xquery40-SequenceTypeUnion">SequenceTypeUnion<!--$idref_lang_part = xquery40- --></nt>  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-VarName">
                     <lhs>VarName</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-SequenceTypeUnion">
                     <lhs>SequenceTypeUnion</lhs>
                     <rhs>
                        <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>  ("|"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-TypeswitchExpr-BracedTypeswitchCases">
                     <lhs>BracedTypeswitchCases</lhs>
                     <rhs>"{"  <nt def="prod-xquery40-TypeswitchCases">TypeswitchCases<!--$idref_lang_part = xquery40- --></nt>  "}"</rhs>
                  </prod>
               </scrap>
               <p role="xquery">The <term>typeswitch</term> expression chooses one of
several expressions to evaluate based on the <termref def="dt-dynamic-type">dynamic type</termref> of an input value.</p>
               <p role="xquery">In a <code nobreak="false">typeswitch</code> expression, the
<code nobreak="false">typeswitch</code> keyword is followed by an expression enclosed
in parentheses, called the <term>operand expression</term>. This is
the expression whose type is being tested. The remainder of the
<code nobreak="false">typeswitch</code> expression consists of one or more
<code nobreak="false">case</code> clauses and a <code nobreak="false">default</code> clause.</p>
               <p role="xquery">Each <code nobreak="false">case</code> clause specifies one or more
<nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>s followed by a
<code nobreak="false">return</code> expression. <termdef term="effective case" id="dt-effective-case">The <term>effective case</term> in a
<code nobreak="false">typeswitch</code> expression is the first <code nobreak="false">case</code>
clause in which the value of the operand expression matches a <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> in the <nt def="doc-xquery40-SequenceType">SequenceTypeUnion<!--$spec = xquery40--></nt> of the <code nobreak="false">case</code>
clause, using the rules of <termref def="dt-sequencetype-matching">SequenceType matching</termref>.
</termdef>

The value of the <code nobreak="false">typeswitch</code> expression is the value of
the <code nobreak="false">return</code> expression in the effective case. If the value
of the operand expression does not match any <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> named in a <code nobreak="false">case</code>
clause, the value of the <code nobreak="false">typeswitch</code> expression is the
value of the <code nobreak="false">return</code> expression in the
<code nobreak="false">default</code> clause.</p>
               <p>In a <code nobreak="false">case</code> or
<code nobreak="false">default</code> clause, if the value to be returned depends on
the value of the operand expression, the clause must specify a
variable name. Within the <code nobreak="false">return</code> expression of the
<code nobreak="false">case</code> or <code nobreak="false">default</code> clause, this variable name
is bound to the value of the operand expression.

Inside a <code nobreak="false">case</code> clause, the <termref def="dt-static-type">static type</termref> of the variable is the
union of the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>s named in the
<nt def="doc-xquery40-SequenceType">SequenceTypeUnion<!--$spec = xquery40--></nt>.  Inside a
<code nobreak="false">default</code> clause, the static type of the variable is the
same as the static type of the operand expression.

If the value to be returned by a <code nobreak="false">case</code> or
<code nobreak="false">default</code> clause does not depend on the value of the
operand expression, the clause need not specify a variable.</p>
               <p>The
scope of a variable binding in a <code nobreak="false">case</code> or
<code nobreak="false">default</code> clause comprises that clause. It is not an error
for more than one <code nobreak="false">case</code> or <code nobreak="false">default</code> clause in
the same <code nobreak="false">typeswitch</code> expression to bind variables with the
same name.
</p>
               <p>Typeswitch expressions have rules regarding the propagation of dynamic
               errors: <phrase diff="chg" at="B">see <specref ref="id-guarded-expressions"/>.
               These rules mean that</phrase> a <code nobreak="false">typeswitch</code> expression ignores (does not raise) any dynamic errors encountered in <code nobreak="false">case</code> clauses other than the <termref def="dt-effective-case">effective case</termref>. Dynamic errors encountered in the <code nobreak="false">default</code> clause are raised only if there is no <termref def="dt-effective-case">effective case</termref>.
An implementation is permitted to raise dynamic errors in the
operand expressions of case clauses that occur before the  <termref def="dt-effective-case">effective
case</termref>, but not required to do so.</p>
               <p role="xquery">The following example shows how a <code nobreak="false">typeswitch</code> expression might
be used to process an expression in a way that depends on its <termref def="dt-dynamic-type">dynamic type</termref>.</p>
               <eg role="parse-test" diff="chg" at="2023-07-01" xml:space="preserve">typeswitch ($customer/billing-address) {
  case $a as element(*, USAddress)     return $a/state
  case $a as element(*, CanadaAddress) return $a/province
  case $a as element(*, JapanAddress)  return $a/prefecture
  default                              return "unknown"
}</eg>
               <p diff="add" at="2023-07-01">The curly brackets in a <code nobreak="false">typeswitch</code> expression are optional. The
            above example can equally be written:</p>
               <eg role="parse-test" xml:space="preserve">typeswitch ($customer/billing-address)
  case $a as element(*, USAddress)     return $a/state
  case $a as element(*, CanadaAddress) return $a/province
  case $a as element(*, JapanAddress)  return $a/prefecture
  default                              return "unknown"
</eg>
               <p>The following example shows a union of sequence types in a single case:</p>
               <eg role="parse-test" xml:space="preserve">typeswitch ($customer/billing-address) {
  case $a as element(*, USAddress) | element(*, MexicoAddress)
    return $a/state
  case $a as element(*, CanadaAddress)
    return $a/province
  case $a as element(*, JapanAddress)
    return $a/prefecture
  default
    return "unknown"
}</eg>
            </div3>
            <div3 id="id-cast">
               <head>Cast</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-CastExpr">
                     <lhs>CastExpr</lhs>
                     <rhs>
                        <nt def="doc-xquery40-PipelineExpr">PipelineExpr<!--$idref_lang_part = xquery40- --></nt>  ("cast"  "as"  <nt def="prod-xquery40-CastTarget">CastTarget<!--$idref_lang_part = xquery40- --></nt>  "?"?)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-CastExpr-PipelineExpr">
                     <lhs>PipelineExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ArrowExpr">ArrowExpr<!--$idref_lang_part = xquery40- --></nt>  ("-&gt;"  <nt def="prod-xquery40-ArrowExpr">ArrowExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="doc-xquery40-CastExpr-CastTarget">
                     <lhs>CastTarget</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EnumerationType">EnumerationType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastExpr-TypeName">
                     <lhs>TypeName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastExpr-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastExpr-ChoiceItemType">
                     <lhs>ChoiceItemType</lhs>
                     <rhs>"("  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt> ++ "|")  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-CastExpr-ItemType">
                     <lhs>ItemType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastExpr-EnumerationType">
                     <lhs>EnumerationType</lhs>
                     <rhs>"enum"  "("  (<nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")"</rhs>
                  </prod>
               </scrap>
               <p>Sometimes
it is necessary to convert a value to a specific datatype. For this
purpose, XQuery 4.0 provides a <code nobreak="false">cast</code> expression that
creates a new value of a specific type based on an existing value. A
<code nobreak="false">cast</code> expression takes two operands: an <term>input
expression</term> and a <term>target type</term>. The type of the
atomized value of the input expression is called the <term>input type</term>. 
The target type must be a <termref def="dt-generalized-atomic-type"/>. In practice
               this means it may be any of:</p>
               <ulist>
                  <item diff="add" at="issue688">
                     <p>The name of an <termref def="dt-named-item-type">named item type</termref>
               defined in the <termref def="dt-static-context"/>, which in turn must refer to an item
               type in one of the following categories.</p>
                  </item>
                  <item>
                     <p>The name of a type defined in the  <termref def="dt-is-types">in-scope schema types</termref>, 
                  which must be a simple type (of variety atomic, list or union) <errorref class="ST" code="0052"/> .
                  In addition, the target type cannot be <code nobreak="false">xs:NOTATION</code>, <code nobreak="false">xs:anySimpleType</code>,
                  or <code nobreak="false">xs:anyAtomicType</code>
                     </p>
                  </item>
                  <item diff="add" at="A">
                     <p>A <code nobreak="false">ChoiceItemType</code> representing a 
                  <termref def="dt-generalized-atomic-type"/> (such as <code nobreak="false">(xs:date | xs:dateTime)</code>).</p>
                  </item>
                  <item diff="add" at="issue688">
                     <p>An <code nobreak="false">EnumerationType</code> such as <code nobreak="false">enum("red", "green", "blue")</code>.</p>
                  </item>
               </ulist>
               <p>Otherwise, a static error is raised <errorref class="ST" code="0080"/>.</p>
               <p>The optional occurrence indicator <code nobreak="false">?</code> denotes that the empty
sequence is permitted.</p>
               <p>Casting a node to <code nobreak="false">xs:QName</code> can cause surprises because it uses the <termref def="dt-static-context"/>
               of the cast expression to provide the <termref def="dt-namespace-binding">namespace bindings</termref> for this operation. 
               Instead of casting to <code nobreak="false">xs:QName</code>, it is generally preferable to use the <function>fn:QName</function> 
               function, which allows the namespace context to be taken from the document containing the QName.</p>
               <p>The semantics of the <code nobreak="false">cast</code> expression
are as follows:</p>
               <olist>
                  <item>
                     <p>The input expression is evaluated.</p>
                  </item>
                  <item>
                     <p>The result of the first step is <termref def="dt-atomization">atomized</termref>.</p>
                  </item>
                  <item>
                     <p> If the result of atomization is a
sequence of more than one atomic item, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                  </item>
                  <item>
                     <p>If the result
of atomization is the empty sequence:</p>
                     <olist>
                        <item>
                           <p>If
<code nobreak="false">?</code> is specified after the target type, the result of the
<code nobreak="false">cast</code> expression is the empty sequence.</p>
                        </item>
                        <item>
                           <p>
If <code nobreak="false">?</code> is not specified after the target type, a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>If the result of atomization is a single
atomic item, the result of the cast expression is determined by
casting to the target type as described in <xspecref spec="FO40" ref="casting"/>. When casting, an
implementation may need to determine whether one type is derived by
restriction from another. An implementation can determine this either
by examining the <termref def="dt-issd">in-scope schema
definitions</termref> or by using an alternative, <termref def="dt-implementation-dependent">implementation-dependent</termref>
mechanism such as a data dictionary.

The result of a cast expression is one of the following: 

<olist>
                           <item>
                              <p> 
    A value of the target type (or, in the case of list types,
    a sequence of values that are instances of the item type of the
    list type).
  </p>
                           </item>
                           <item>
                              <p> 
    A type error, if casting from the source type to the
    target type is not supported (for example attempting to convert an
    integer to a date).
  </p>
                           </item>
                           <item>
                              <p> 
    A dynamic error, if the particular input value cannot be
    converted to the target type (for example, attempting to convert
    the string <code nobreak="false">"three"</code> to an integer).
  </p>
                           </item>
                        </olist>
                     </p>
                     <note diff="add" at="issue688">
                        <p>Casting to an enumeration type relies on the fact that an enumeration type
                  is a generalized atomic type. So the expression <code nobreak="false">cast $x as enum("red", "green")</code> 
                  has the following effect:</p>
                        <ulist>
                           <item>
                              <p>If <code nobreak="false">$x</code> is an instance of <code nobreak="false">xs:string</code>,
                           the expression returns <code nobreak="false">$x</code> unchanged if it is one of the
                           permitted strings, and raises a dynamic error otherwise;</p>
                           </item>
                           <item>
                              <p>In other cases, the expression first casts <code nobreak="false">$x</code> to
                     <code nobreak="false">xs:string</code>, and then proceeds as above.</p>
                           </item>
                        </ulist>
                     </note>
                  </item>
               </olist>
            </div3>
            <div3 id="id-castable">
               <head>Castable</head>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-CastableExpr">
                     <lhs>CastableExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CastExpr">CastExpr<!--$idref_lang_part = xquery40- --></nt>  ("castable"  "as"  <nt def="prod-xquery40-CastTarget">CastTarget<!--$idref_lang_part = xquery40- --></nt>  "?"?)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-CastableExpr-CastExpr">
                     <lhs>CastExpr</lhs>
                     <rhs>
                        <nt def="doc-xquery40-PipelineExpr">PipelineExpr<!--$idref_lang_part = xquery40- --></nt>  ("cast"  "as"  <nt def="prod-xquery40-CastTarget">CastTarget<!--$idref_lang_part = xquery40- --></nt>  "?"?)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-CastableExpr-CastTarget">
                     <lhs>CastTarget</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EnumerationType">EnumerationType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastableExpr-TypeName">
                     <lhs>TypeName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastableExpr-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastableExpr-ChoiceItemType">
                     <lhs>ChoiceItemType</lhs>
                     <rhs>"("  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt> ++ "|")  ")"</rhs>
                  </prod>

                  <prod id="doc-xquery40-CastableExpr-ItemType">
                     <lhs>ItemType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="doc-xquery40-CastableExpr-EnumerationType">
                     <lhs>EnumerationType</lhs>
                     <rhs>"enum"  "("  (<nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")"</rhs>
                  </prod>
               </scrap>
               <p>XQuery 4.0
provides an expression that tests whether a given value
is castable into a given target type. 

The <phrase diff="chg" at="A">target type</phrase> is subject to the same
               rules as the target type of a <code nobreak="false">cast</code> expression.</p>
               <p>The expression <code role="parse-test" nobreak="false">E castable as T</code> returns <code nobreak="false">true</code> 
if the result of evaluating <code nobreak="false">E</code>  
can be successfully cast into the target type <code nobreak="false">T</code> by using a <code nobreak="false">cast</code> expression; 
otherwise it returns <code nobreak="false">false</code>. 
If evaluation of <code nobreak="false">E</code> fails with a dynamic error or if the value of <code nobreak="false">E</code> cannot be atomized, 
the <code nobreak="false">castable</code> expression as a whole fails.</p>
               <p>The <code nobreak="false">castable</code> expression can be used as a <termref def="dt-predicate">predicate</termref>  to
avoid errors at evaluation time. 
It can also be used to select an appropriate type for processing of a given value, as illustrated in
the following example:</p>
               <eg role="parse-test" xml:space="preserve">
if ($x castable as hatsize)
then $x cast as hatsize
else if ($x castable as IQ)
then $x cast as IQ
else $x cast as xs:string</eg>
               <note diff="add" at="issue688">
                  <p>The expression <code nobreak="false">$x castable as enum("red", "green", "blue")</code>
               is for most practical purposes equivalent to <code nobreak="false">$x = ("red", "green", "blue")</code>;
            the main difference is that it uses the Unicode codepoint collation for comparing strings,
            not the default collation from the static context.</p>
               </note>
            </div3>
            <div3 id="id-constructor-functions">
               <head>Constructor Functions</head>
               <p>For every simple type in the <termref def="dt-is-types">in-scope schema types</termref>  (except <code nobreak="false">xs:NOTATION</code> and 
               <code nobreak="false">xs:anyAtomicType</code>, and <code nobreak="false">xs:anySimpleType</code>, which 
               are not instantiable), a <term>constructor function</term> is implicitly defined. 
               In each case, the name of the constructor function is the same as the name of 
               its target type (including namespace). The signature of the constructor 
               function for  a given type depends on the type that is being constructed, 
               and can be found in <xspecref spec="FO40" ref="constructor-functions"/>.</p>
               <p>There is also a constructor function for every <termref def="dt-named-item-type"/> 
               in the <termref def="dt-static-context"/>
            that expands either to a <termref def="dt-generalized-atomic-type"/>
                  <phrase diff="add" at="issue617">or to
            a <nt def="doc-xquery40-RecordType">RecordType<!--$spec = xquery40--></nt>
                  </phrase>.</p>
               <p>All such constructor functions are classified as
               <termref def="dt-system-function">system functions</termref>.</p>
               <note diff="add" at="issue617">
                  <p>The constructor function is present in the static
            context if and only if the corresponding type is present in the static context.</p>
                  <p>For XSLT, this means that a constructor function corresponding to an imported
            schema type is private to the stylesheet package, and a constructor function
            corresponding to an <code nobreak="false">xsl:item-type</code> declaration has the same visibility
               as the <code nobreak="false">xsl:item-type</code> declaration.</p>
                  <p>For XQuery, this means that a constructor function corresponding to an imported
                  schema type is private to the query module, and a constructor function
                  corresponding to a named item type declaration is <code nobreak="false">%public</code>
                  or <code nobreak="false">%private</code> according to the annotations on the item type declaration.</p>
               </note>
               <p>
                  <termdef term="constructor function" id="dt-constructor-function">The <term>constructor function</term> for a given simple type is used to convert instances of other  simple types into the given type. 
                  The semantics of the constructor function call <code nobreak="false">T($arg)</code> are defined to be equivalent to the expression <code role="parse-test" nobreak="false">$arg cast as T?</code>.</termdef>
               </p>
               <p>The following examples illustrate the use of constructor functions:</p>
               <ulist>
                  <item>
                     <p>This
example is equivalent to <code role="parse-test" nobreak="false">"2000-01-01" cast as
xs:date?</code>.</p>
                     <eg role="parse-test" xml:space="preserve">xs:date("2000-01-01")</eg>
                  </item>
                  <item>
                     <p>This
example is equivalent to

<code role="parse-test" nobreak="false">($floatvalue * 0.2E-5) cast as xs:decimal?</code>.</p>
                     <eg role="parse-test" xml:space="preserve">xs:decimal($floatvalue * 0.2E-5)</eg>
                  </item>
                  <item>
                     <p>This example returns an
<code nobreak="false">xs:dayTimeDuration</code> value equal to 21 days. It is
equivalent to <code role="parse-test" nobreak="false">"P21D" cast as xs:dayTimeDuration?</code>.</p>
                     <eg role="parse-test" xml:space="preserve">xs:dayTimeDuration("P21D")</eg>
                  </item>
                  <item diff="add" at="issue688">
                     <p>If
                     <code nobreak="false">usa:zipcode</code> is a user-defined <termref def="dt-atomic-type"/>
in the <termref def="dt-is-types">in-scope schema types</termref>, then the
following expression is equivalent to the
expression <code role="parse-test" nobreak="false">("12345" cast as
usa:zipcode?)</code>.</p>
                     <eg role="parse-test" xml:space="preserve">usa:zipcode("12345")</eg>
                  </item>
                  <item>
                     <p>If <code nobreak="false">my:chrono</code> is a named item type that expands to
                     <code nobreak="false">(xs:date | xs:time | xs:dateTime)</code>, then the result
                     of <code nobreak="false">my:chrono("12:00:00Z")</code> is the <code nobreak="false">xs:time</code>
                     value <code nobreak="false">12:00:00Z</code>.</p>
                  </item>
                  <item diff="add" at="issue617">
                     <p>If <code nobreak="false">my:location</code> is a named item type that expands
                  to <code nobreak="false">record(latitude as xs:double, longitude as xs:double)</code>,
                  then the result of <code nobreak="false">my:location(50.52, -3.02)</code> is
                  the map <code nobreak="false">{ 'latitude': 50.52e0, 'longitude': -3.02e0 }</code>.</p>
                  </item>
               </ulist>
               <note>
                  <p>
                  An instance of an <termref def="dt-atomic-type"/> whose name is in no namespace can be
  constructed by using a <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$spec = xquery40--></nt> 
  in either a cast expression or a constructor function call.  Examples:
  </p>
                  <eg role="parse-test" xml:space="preserve">17 cast as Q{}apple</eg>
                  <eg role="parse-test" xml:space="preserve">Q{}apple(17)</eg>
                  <p diff="chg" at="A">In either context, using an unqualified NCName might not work:
                  in a cast expression, an unqualified name is it is interpreted
                  according to the <termref def="dt-default-namespace-elements-and-types"/>,
                  while an unqualified name in a constructor function call is resolved using the
                  <termref def="dt-default-function-namespace"/> which will often be inappropriate.
               </p>
               </note>
            </div3>
            <div3 id="id-treat">
               <head>Treat</head>
               <changes>
                  <change issue="2165">The <code nobreak="false">treat as</code> expression now raises
               a type error rather than a dynamic error when it fails.</change>
               </changes>
               <scrap headstyle="show">
                  <prod id="doc-xquery40-TreatExpr">
                     <lhs>TreatExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CastableExpr">CastableExpr<!--$idref_lang_part = xquery40- --></nt>  ("treat"  "as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-TreatExpr-CastableExpr">
                     <lhs>CastableExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CastExpr">CastExpr<!--$idref_lang_part = xquery40- --></nt>  ("castable"  "as"  <nt def="prod-xquery40-CastTarget">CastTarget<!--$idref_lang_part = xquery40- --></nt>  "?"?)?</rhs>
                  </prod>

                  <prod id="doc-xquery40-TreatExpr-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>
               </scrap>
               <p>The expression <code nobreak="false">
                     <var>E</var> treat as <var>T</var>
                  </code>
            evaluates the subexpression <var>E</var> to produce a value <var>V</var>,
               and then checks whether <var>V</var> matches
            the <termref def="dt-sequence-type"/>
                  <var>T</var>. If it matches,
            the result of the expression is <var>V</var>; otherwise, the expression
            fails with a type error <errorref class="DY" code="0050"/>.</p>
               <p>The value <var>V</var> must be an actual instance of the type <var>T</var>.
            No casting or coercion is applied to change the value to make it an instance
            of <var>T</var>. The result of the expression is equivalent to:</p>
               <eg xml:space="preserve">let $V := <var>E</var>
return if ($V instance of <var>T</var>)
       then $V
       else error(#err:XPDY0050)</eg>
               <ulist>
                  <item>
                     <p>Example:</p>
                     <eg role="parse-test" xml:space="preserve">$myaddress treat as element(*, USAddress)</eg>
                     <p>The
<termref def="dt-static-type">static type</termref> of
<code nobreak="false">$myaddress</code> may be <code nobreak="false">element(*, Address)</code>, a
less specific type than <code nobreak="false">element(*, USAddress)</code>. However,
at run-time, the value of <code nobreak="false">$myaddress</code> must match the type
<code nobreak="false">element(*, USAddress)</code> using rules for <termref def="dt-sequencetype-matching">SequenceType
matching</termref>;
otherwise a <termref def="dt-type-error"/> is
raised <errorref class="DY" code="0050"/>.</p>
                  </item>
               </ulist>
               <note>
                  <p>Earlier releases of XPath and XQuery defined a mode of operation,
               sometimes called strict static typing, in which it was required that the static
               type of every expression should conform to the required type of the context
               in which it appeared. In this situation it was often necessary to define
               a more precise static type for an expression by the use of <code nobreak="false">treat as</code>.
               In the absence of this feature, the <code nobreak="false">treat as</code> expression is
               rarely necessary, though it can be useful for documentation, and might in
               some cases (depending on the processor) have performance benefits.
             </p>
                  <p>XQuery 4.0 redefines the error raised by a <code nobreak="false">treat as</code> expression
             as a type error rather than a dynamic error, which allows a processor to raise
             the error statically in the case of an expression (such as <code nobreak="false">3 treat as xs:string</code>)
             which can never succeed. However, the error code remains unchanged, for compatibility.</p>
               </note>
            </div3>
         </div2>
         <div2 id="id-pipeline-operator">
            <head>Pipeline operator</head>
            <changes>
               <change issue="1685" PR="1686" date="2025-01-09">
               With the pipeline operator <code nobreak="false">-&gt;</code>, the result of an expression
               can be bound to the context value before evaluating another expression.
            </change>
            </changes>
            <scrap headstyle="show">
               <head/>
               <prod id="doc-xquery40-PipelineExpr">
                  <lhs>PipelineExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ArrowExpr">ArrowExpr<!--$idref_lang_part = xquery40- --></nt>  ("-&gt;"  <nt def="prod-xquery40-ArrowExpr">ArrowExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-PipelineExpr-ArrowExpr">
                  <lhs>ArrowExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-UnaryExpr">UnaryExpr<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-SequenceArrowTarget">SequenceArrowTarget<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MappingArrowTarget">MappingArrowTarget<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>
            </scrap>
            <p diff="add" at="A">
               <termdef term="pipeline operator" id="dt-pipeline-operator">
            The <term>pipeline operator</term>
                  <code nobreak="false">-&gt;</code> evaluates an expression and
            binds the result to the context value before evaluating another expression.</termdef>
            </p>
            <p>Each operation <code nobreak="false">
                  <var>E1</var> -&gt; <var>E2</var>
               </code> is evaluated as follows: 
            Expression <var>E1</var> is evaluated to a sequence <code nobreak="false">S</code>. 
            <var>S</var> then serves in turn to provide an inner <termref def="dt-fixed-focus"/>
            (with the context value set to <var>S</var>) for an evaluation of <var>E2</var> in the
            <termref def="dt-dynamic-context">dynamic context</termref>.
            Unlike the <specref ref="id-map-operator"/>, the result of <var>E1</var> is bound
            just once and as a whole to the context value.
         </p>
            <p>The following examples illustrate the use of pipeline operators:</p>
            <example>
               <ulist>
                  <item>
                     <p>Tokenizes a string, counts the tokens, creates a concatenated string and returns
                     <code nobreak="false">count=3</code>:</p>
                     <eg role="parse-test" xml:space="preserve">'a b c' -&gt; tokenize(.) -&gt; count(.) -&gt; concat('count=', .)
</eg>
                     <p>An equivalent expression is:
                     <eg role="parse-test" xml:space="preserve">
let $string := 'a b c'
let $tokens := tokenize($string)
let $count := count($tokens)
return concat('count=', $count)
                     </eg>
                     </p>
                  </item>
                  <item>
                     <p>Calculates the sum of powers of <code nobreak="false">2</code> and returns
                     <code nobreak="false">2046</code>.</p>
                     <eg role="parse-test" xml:space="preserve">(1 to 10) ! math:pow(2, .) -&gt; sum(.)</eg>
                     <p>An equivalent expression is:
                     <eg role="parse-test" xml:space="preserve">
let $powers := (
  for $exp in 1 to 10
  return math:pow(2, $exp)
)
return sum($powers)
                     </eg>
                     </p>
                  </item>
                  <item>
                     <p>Doubles the values of a sequence, compares the values pairwise with another
                     sequence, checks if some comparisons were successful, and returns
                     <code nobreak="false">true</code>.</p>
                     <eg role="parse-test" xml:space="preserve">
(1 to 4)
-&gt; for-each(., op('+'))
-&gt; for-each-pair(4 to 7, ., op('&gt;'))
-&gt; some(.)
                  </eg>
                     <p>An equivalent expression is:
                     <eg role="parse-test" xml:space="preserve">
let $data := 1 to 4
let $data := for-each($data, op('+'))
let $data := for-each-pair(4 to 7, $data, op('&gt;'))
return some($data)
                     </eg>
                     </p>
                  </item>
                  <item>
                     <p>Reduces a long sequence to at most 9 elements, with dots appended,
                  and returns a single string.</p>
                     <eg role="parse-test" xml:space="preserve">
$dictionary/word
-&gt; (if (count(.) &lt; 10) then . else (.[1 to 9], '…'))
-&gt; string-join(., '; ')
                  </eg>
                     <p>An equivalent expression is:
                     <eg role="parse-test" xml:space="preserve">
let $words := $dictionary/word
let $chopped := (if (count($words) &lt; 10) then $words else ($words[1 to 9], '…'))
return string-join($chopped, '; ')
                     </eg>
                     </p>
                  </item>
               </ulist>
            </example>
         </div2>
         <div2 id="id-map-operator">
            <head>Simple map operator (<code nobreak="false">!</code>)</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-SimpleMapExpr">
                  <lhs>SimpleMapExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-PathExpr">PathExpr<!--$idref_lang_part = xquery40- --></nt>  ("!"  <nt def="prod-xquery40-PathExpr">PathExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-SimpleMapExpr-PathExpr">
                  <lhs>PathExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AbsolutePathExpr">AbsolutePathExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-RelativePathExpr">RelativePathExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-leading-lone-slash">xgc: leading-lone-slash</loc>
                  </com>
               </prod>
            </scrap>
            <p>
    A mapping expression <code nobreak="false">
                  <var>S</var>!<var>E</var>
               </code> evaluates the
    expression <var>E</var> once for every item in the sequence
    obtained by evaluating <var>S</var>. The simple mapping operator
    <code nobreak="false">!</code> can be applied to any sequence, regardless of the
    types of its items, and it can deliver a mixed sequence of nodes,
    atomic items, and functions. Unlike the similar <code nobreak="false">/</code>
    operator, it does not sort nodes into document order or eliminate
    duplicates.
  </p>
            <p>Each operation <code nobreak="false">
                  <var>E1</var>!<var>E2</var>
               </code> is evaluated as follows: 
            Expression <var>E1</var> is evaluated to a sequence <code nobreak="false">S</code>. 
            Each item in <var>S</var> then serves in turn to provide an inner focus 
            (the item as the context value, its position in <var>S</var> as the 
            context position, the length of <var>S</var> as the context size) 
            for an evaluation of <var>E2</var> in the <termref def="dt-dynamic-context">dynamic context</termref>. The sequences resulting from all the 
            evaluations of <var>E2</var> are combined as follows: Every evaluation 
            of <var>E2</var> returns a (possibly empty) sequence of items. 
            The final result is the <termref def="dt-sequence-concatenation"/> of these sequences.
            The returned sequence preserves the orderings within and among the subsequences 
            generated by the evaluations of <var>E2</var>.
         </p>
            <p>Simple map operators have functionality similar to <specref ref="id-path-operator"/>.
  The following table summarizes the differences between these two operators</p>
            <table role="medium" width="100%">
               <thead>
                  <tr>
                     <th rowspan="1" colspan="1">Operator</th>
                     <th rowspan="1" colspan="1">Path operator (<code nobreak="false">E1 / E2</code>)</th>
                     <th rowspan="1" colspan="1">Simple map operator (<code nobreak="false">E1 ! E2</code>)</th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <th rowspan="1" colspan="1">E1</th>
                     <td rowspan="1" colspan="1">Any sequence of nodes</td>
                     <td rowspan="1" colspan="1">Any sequence of items</td>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">E2</th>
                     <td rowspan="1" colspan="1">Either a sequence of nodes or a sequence of non-node items</td>
                     <td rowspan="1" colspan="1">A sequence of items</td>
                  </tr>
                  <tr>
                     <th rowspan="1" colspan="1">Additional processing</th>
                     <td rowspan="1" colspan="1">Duplicate elimination and document ordering</td>
                     <td rowspan="1" colspan="1">Simple <termref def="dt-sequence-concatenation"/>
                     </td>
                  </tr>
               </tbody>
            </table>
            <p>The following examples illustrate the use of simple map operators combined with path expressions.</p>
            <example>
               <ulist>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">child::div1 / child::para / string() ! concat("id-", .)</code>
                     </p>
                     <p>Selects the <code nobreak="false">para</code> element children of the <code nobreak="false">div1</code> element children of the context node; that is, the <code nobreak="false">para</code> element grandchildren of the context node that have <code nobreak="false">div1</code> parents. It then outputs the strings obtained by prepending <code nobreak="false">"id-"</code> to each of the string values of these grandchildren.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">$emp ! (@first, @middle, @last)</code>
                     </p>
                     <p>Returns the values of the attributes <code nobreak="false">first</code>, <code nobreak="false">middle</code>, and <code nobreak="false">last</code> for each element in <code nobreak="false">$emp</code>, in the order given. (The <code nobreak="false">/</code> operator, if used here, would return the attributes in an unpredictable order.)</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">$docs ! ( //employee)</code>
                     </p>
                     <p>Returns all the <code nobreak="false">employee</code> elements within all the documents identified by the variable <code nobreak="false">$docs</code>, in document order within each document, but retaining the order of documents.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">avg( //employee / salary ! translate(., '$', '') ! number(.))</code>
                     </p>
                     <p>Returns the average salary of the employees, having converted the salary to a number by removing any <code nobreak="false">$</code> sign and then converting to a number. (The second occurrence of <code nobreak="false">!</code> could not be written as <code nobreak="false">/</code> because the left-hand operand of <code nobreak="false">/</code> cannot be an atomic item.)</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">string-join((1 to $n) ! "*")</code>
                     </p>
                     <p>Returns a string containing <code nobreak="false">$n</code> asterisks.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">$values ! (.*.) =&gt; sum()</code>
                     </p>
                     <p>Returns the sum of the squares of a sequence of numbers.</p>
                  </item>
                  <item>
                     <p>
                        <code role="parse-test" nobreak="false">string-join(ancestor::* ! name(), '/')</code>
                     </p>
                     <p>Returns the names of ancestor elements, joined by <code nobreak="false">/</code> characters, i.e., the path to the parent of the context.</p>
                  </item>
               </ulist>
            </example>
         </div2>
         <div2 id="id-arrow-operator">
            <head>Arrow Expressions</head>
            <changes>
               <change issue="1716 1829" PR="1763 1830" date="2025-02-25">The syntax on the right-hand side of an arrow operator
               has been relaxed; a dynamic function call no longer needs to start with a variable reference
            or a parenthesized expression, it can also be (for example) an inline function expression
            or a map or array constructor.</change>
            </changes>
            <p>Arrow expressions apply a function (or more generally, a sequence of functions) to a value, using the value of the
         left-hand expression as the first argument to the function.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ArrowExpr">
                  <lhs>ArrowExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-UnaryExpr">UnaryExpr<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-SequenceArrowTarget">SequenceArrowTarget<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MappingArrowTarget">MappingArrowTarget<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-UnaryExpr">
                  <lhs>UnaryExpr</lhs>
                  <rhs>("-"  |  "+")*  <nt def="prod-xquery40-ValueExpr">ValueExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-SequenceArrowTarget">
                  <lhs>SequenceArrowTarget</lhs>
                  <rhs>"=&gt;"  <nt def="prod-xquery40-ArrowTarget">ArrowTarget<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-ArrowTarget">
                  <lhs>ArrowTarget</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FunctionCall">FunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-RestrictedDynamicCall">RestrictedDynamicCall<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-FunctionCall">
                  <lhs>FunctionCall</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-ArgumentList">ArgumentList<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                  </com>
                  <com>
                     <loc href="#parse-note-parens">gn: parens</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-RestrictedDynamicCall">
                  <lhs>RestrictedDynamicCall</lhs>
                  <rhs>(<nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionItemExpr">FunctionItemExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MapConstructor">MapConstructor<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArrayConstructor">ArrayConstructor<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-VarRef">
                  <lhs>VarRef</lhs>
                  <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-ParenthesizedExpr">
                  <lhs>ParenthesizedExpr</lhs>
                  <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-FunctionItemExpr">
                  <lhs>FunctionItemExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-NamedFunctionRef">NamedFunctionRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-InlineFunctionExpr">InlineFunctionExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-NamedFunctionRef">
                  <lhs>NamedFunctionRef</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "#"  <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-InlineFunctionExpr">
                  <lhs>InlineFunctionExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  ("function"  |  "fn")  <nt def="prod-xquery40-FunctionSignature">FunctionSignature<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-FunctionBody">FunctionBody<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-MapConstructor">
                  <lhs>MapConstructor</lhs>
                  <rhs>"map"?  "{"  (<nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$idref_lang_part = xquery40- --></nt> ** ",")  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-ArrayConstructor">
                  <lhs>ArrayConstructor</lhs>
                  <rhs>
                     <nt def="prod-xquery40-SquareArrayConstructor">SquareArrayConstructor<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CurlyArrayConstructor">CurlyArrayConstructor<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-PositionalArgumentList">
                  <lhs>PositionalArgumentList</lhs>
                  <rhs>"("  <nt def="prod-xquery40-PositionalArguments">PositionalArguments<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-PositionalArguments">
                  <lhs>PositionalArguments</lhs>
                  <rhs>(<nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-ArrowExpr-MappingArrowTarget">
                  <lhs>MappingArrowTarget</lhs>
                  <rhs>"=!&gt;"  <nt def="prod-xquery40-ArrowTarget">ArrowTarget<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p>The arrow syntax is particularly helpful when applying multiple
            functions to a value in turn. For example, the following
            expression invites syntax errors due to misplaced parentheses:
         </p>
            <eg role="parsetest" xml:space="preserve">tokenize((normalize-unicode(upper-case($string))),"\s+")</eg>
            <p>In the following reformulation, it is easier to see that the parentheses are balanced:</p>
            <eg role="parse-test" xml:space="preserve">$string =&gt; upper-case() =&gt; normalize-unicode() =&gt; tokenize("\s+")</eg>
            <p diff="add" at="A">When the operator is written as <code nobreak="false">=!&gt;</code>, the function
            is applied to each item in the sequence in turn. 
            Assuming that <code nobreak="false">$string</code> is a single string, the above example could
            equally be written:</p>
            <eg role="parse-test" xml:space="preserve">$string =!&gt; upper-case() =!&gt; normalize-unicode() =!&gt; tokenize("\s+")</eg>
            <p diff="add" at="A">The difference between the two operators is seen when the left-hand
            operand evaluates to a sequence:</p>
            <eg role="parse-test" xml:space="preserve">(1, 2, 3) =&gt; avg()</eg>
            <p diff="add" at="2023-07-24">returns a value of only one item, <code nobreak="false">2</code>, the average of all three items. </p>
            <p>This example could also be written as using the <termref def="dt-pipeline-operator"/> as:</p>
            <eg xml:space="preserve">(1, 2, 3) -&gt; avg(.)</eg>
            <p>By contrast, an expression using the <termref def="dt-mapping-arrow-operator"/>:</p>
            <eg role="parse-test" xml:space="preserve">(1, 2, 3) =!&gt; avg()</eg>
            <p diff="add" at="2023-07-24">would return the original sequence of three items, <code nobreak="false">(1, 2, 3)</code>, 
            each item being the average of itself.</p>
            <p>There are two significant differences between the <termref def="dt-pipeline-operator"/>
               <code nobreak="false">-&gt;</code>
            and the <termref def="dt-sequence-arrow-operator"/>
               <code nobreak="false">=&gt;</code>:</p>
            <ulist>
               <item>
                  <p>The <code nobreak="false">-&gt;</code> operator takes an arbitrary expression as its right-hand operand,
            whereas the <code nobreak="false">=&gt;</code> operator requires the right-hand operand to be a function call.</p>
               </item>
               <item>
                  <p>When the right hand operand is a function call, the first argument
            is omitted in the case of the <code nobreak="false">=&gt;</code> operator, but is included explicitly
            (as a context value expression, <code nobreak="false">.</code>) in the case of the <code nobreak="false">-&gt;</code> operator.</p>
               </item>
            </ulist>
            <p>The following example:</p>
            <eg role="parse-test" xml:space="preserve">"The cat sat on the mat"
=&gt; tokenize()
=!&gt; concat(".")
=!&gt; upper-case()
=&gt; string-join(" ")</eg>
            <p>returns <code nobreak="false">"THE. CAT. SAT. ON. THE. MAT."</code>. The first arrow
            could be written either as <code nobreak="false">=&gt;</code> or <code nobreak="false">=!&gt;</code> because the operand is a 
            <termref def="dt-singleton"/>; the next two

            arrows have to be <code nobreak="false">=!&gt;</code> because the function is applied to each item in the tokenized
            sequence individually; the final arrow must be <code nobreak="false">=&gt;</code> because the <code nobreak="false">string-join</code>
            function applies to the sequence as a whole.</p>
            <note>
               <p>It may be useful to think of this as a map/reduce pipeline. The functions
            introduced by <code nobreak="false">=!&gt;</code> are mapping operations; the function introduced by <code nobreak="false">=&gt;</code>
            is a reduce operation.</p>
            </note>
            <p>The following example introduces an inline function to the pipeline:</p>
            <eg role="parse-test" diff="add" at="A" xml:space="preserve">(1 to 5) =!&gt; xs:double() =!&gt; math:sqrt() =!&gt; fn($a) { $a + 1 }() =&gt; sum()</eg>
            <p>This is equivalent to <code nobreak="false">sum((1 to 5) ! (math:sqrt(xs:double(.)) + 1))</code>.</p>
            <p>The same effect can be achieved using a <termref def="dt-focus-function"/>:</p>
            <eg role="parse-test" xml:space="preserve">(1 to 5) =!&gt; xs:double() =!&gt; math:sqrt() =!&gt; fn { . + 1 }() =&gt; sum()</eg>
            <p>It could also be expressed using the mapping operator <code nobreak="false">!</code>:</p>
            <eg role="parse-test" xml:space="preserve">(1 to 5) ! xs:double(.) ! math:sqrt(.) ! (. + 1) =&gt; sum()</eg>
            <note diff="add" at="A">
               <p>The <code nobreak="false">ArgumentList</code> may include <code nobreak="false">PlaceHolders</code>,
            though this is not especially useful. For example, the expression <code nobreak="false">"$" =&gt; concat(?)</code> is equivalent
            to <code nobreak="false">concat("$", ?)</code>: its value is a function that prepends a supplied string with
            a <code nobreak="false">$</code> symbol.</p>
            </note>
            <note diff="add" at="A">
               <p>The <code nobreak="false">ArgumentList</code> may include keyword arguments if the
            function is identified statically (that is, by name). For example,
            the following is valid: <code nobreak="false">$xml =&gt; xml-to-json(indent := true()) =&gt; parse-json(escape := false())</code>.</p>
            </note>
            <p diff="add" at="A">The sequence arrow operator thus applies the supplied function to 
            the left-hand operand as a whole, while the mapping arrow operator applies the function to
            each item in the value of the left-hand operand individually. In the case where the result
            of the left-hand operand is a single item, the two operators have the same effect.</p>
            <note>
               <p>The mapping arrow symbol <code nobreak="false">=!&gt;</code> is intended to suggest a combination of
            function application (<code nobreak="false">=&gt;</code>) and sequence mapping
            (<code nobreak="false">!</code>) combined in a single operation.</p>
               <p>Similarly, the method call operator <code nobreak="false">=?&gt;</code> is intended to suggest a combination
               of function application (<code nobreak="false">=&gt;</code>) and map lookup (<code nobreak="false">?</code>) in a single
            operation.</p>
            </note>
            <p>The construct on the right-hand side of the arrow operator (<code nobreak="false">=&gt;</code>) can
         either be a static function call, or a restricted form of dynamic function call. The
         restrictions are there to ensure that the two forms can be distinguished by the parser
         with limited lookahead. For a dynamic call, the function item(s) to be called can be 
         expressed as a variable reference, an inline function expression, a named function reference, 
         a map constructor, or an array constructor. Any other expression used to return the required function
         item must be enclosed in parentheses.</p>
            <p>Because the semantics of the arrow operator (<code nobreak="false">=&gt;</code>) are defined in terms of
         static and dynamic functions calls, it is possible for the right-hand side to deliver
         a sequence of functions; the result of the arrow expression is the sequence-concatenation
         of the results of the function calls. For example,</p>
            <eg xml:space="preserve">"London" =&gt; (upper-case#1, lower-case#1, string-length#1)</eg>
            <p>returns the sequence <code nobreak="false">("LONDON", "london", 6)</code>.</p>
            <div3 id="id-sequence-arrow-expression">
               <head>Sequence Arrow Expressions</head>
               <p diff="add" at="2023-04-18">
                  <termdef term="sequence arrow operator" id="dt-sequence-arrow-operator">
               The <term>sequence arrow operator</term>
                     <code nobreak="false">=&gt;</code> applies a function to a
               supplied sequence.</termdef> It is defined as follows:</p>
               <ulist>
                  <item>
                     <p>If the arrow is followed by a static <nt def="doc-xquery40-FunctionCall">FunctionCall<!--$spec = xquery40--></nt>:</p>
                     <p>Given a  <nt def="doc-xquery40-UnaryExpr">UnaryExpr<!--$spec = xquery40--></nt>
                        <var>U</var> and a <nt def="doc-xquery40-FunctionCall">FunctionCall<!--$spec = xquery40--></nt>
                        <code nobreak="false">
                           <var>F</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code>, 
                  the expression <code nobreak="false">
                           <var>U</var> =&gt; <var>F</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code> 
                  is equivalent to the expression 
                  <code nobreak="false">
                           <var>F</var>(<var>U</var>, <var>A</var>, <var>B</var>, <var>C</var>...)</code>.</p>
                  </item>
                  <item>
                     <p>If the arrow is followed by a <nt def="prod-xquery40-RestrictedDynamicCall">RestrictedDynamicCall<!--$spec = xquery40--></nt>:</p>
                     <p>Given a  <nt def="doc-xquery40-UnaryExpr">UnaryExpr<!--$spec = xquery40--></nt>
                        <var>U</var>, and a <nt def="prod-xquery40-RestrictedDynamicCall">RestrictedDynamicCall<!--$spec = xquery40--></nt>
                        <code nobreak="false">
                           <var>E</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code>, the expression 
                  <code nobreak="false">
                           <var>U</var> =&gt; <var>E</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code> is equivalent to the
                  dynamic function call <code nobreak="false">
                           <var>E</var>(<var>U</var>, <var>A</var>, <var>B</var>, <var>C</var>...)</code>.</p>
                  </item>
               </ulist>
               <!--<note><p>Although the syntax of an arrow expression makes use of the grammatical productions
            <nt def="FunctionCall">FunctionCall</nt> and <nt def="DynamicFunctionCall">DynamicFunctionCall</nt>,
            these are not evaluated in the same way as a function call that appears as a 
            free-standing expression.</p></note>-->
            </div3>
            <div3 id="id-mapping-arrow-expression">
               <head>Mapping Arrow Expressions</head>
               <changes>
                  <change>
               The arrow operator <code nobreak="false">=&gt;</code> is now complemented by a “mapping arrow” operator <code nobreak="false">=!&gt;</code>
               which applies the supplied function to each item in the input sequence independently.
            </change>
               </changes>
               <p>
                  <termdef term="mapping arrow operator" id="dt-mapping-arrow-operator">
            The <term>mapping arrow operator</term>
                     <code nobreak="false">=!&gt;</code> applies a function to each
            item in a sequence.</termdef> It is defined as follows:</p>
               <ulist>
                  <item>
                     <p>If the arrow is followed by a static <nt def="doc-xquery40-FunctionCall">FunctionCall<!--$spec = xquery40--></nt>:</p>
                     <p>Given a <nt def="doc-xquery40-UnaryExpr">UnaryExpr<!--$spec = xquery40--></nt>
                        <var>U</var> and a <nt def="doc-xquery40-FunctionCall">FunctionCall<!--$spec = xquery40--></nt>
                        <code nobreak="false">
                           <var>F</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code>, 
                  the expression <code nobreak="false">
                           <var>U</var> =!&gt; <var>F</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code> 
                  is equivalent to the expression 
                  <code nobreak="false">for $u in <var>U</var> return 
                     <var>F</var>(<var>$u</var>, <var>A</var>, <var>B</var>, <var>C</var>...)</code>.</p>
                  </item>
                  <item>
                     <p>If the arrow is followed by a <nt def="prod-xquery40-RestrictedDynamicCall">RestrictedDynamicCall<!--$spec = xquery40--></nt>:</p>
                     <p>Given a  <nt def="doc-xquery40-UnaryExpr">UnaryExpr<!--$spec = xquery40--></nt>
                        <var>U</var>, and a <nt def="prod-xquery40-RestrictedDynamicCall">RestrictedDynamicCall<!--$spec = xquery40--></nt>
                        <code nobreak="false">
                           <var>E</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code>, the expression 
               <code nobreak="false">
                           <var>U</var> =&gt; <var>E</var>(<var>A</var>, <var>B</var>, <var>C</var>...)</code> is equivalent to the
               expression <code nobreak="false">for $u in U return <var>E</var>(<var>$u</var>, <var>A</var>, <var>B</var>, <var>C</var>...)</code>.</p>
                  </item>
               </ulist>
            </div3>
         </div2>
         <div2 id="id-validate" role="xquery">
            <head>Validate Expressions</head>
            <changes>
               <change issue="729" PR="1254" date="2024-06-08">
                  The rules concerning the interpretation of <code nobreak="false">xsi:schemaLocation</code>
                  and <code nobreak="false">xsi:noNamespaceSchemaLocation</code> attributes have been tightened up.
               </change>
               <change issue="2029" PR="2030" date="2025-05-28">
                  The technical details of how validation works have been moved to the
                  <emph>Functions and Operators</emph> specification. The XQuery <code nobreak="false">validate</code>
               expression is now defined in terms of the new <function>xsd-validator</function> function.
               </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ValidateExpr">
                  <lhs>ValidateExpr</lhs>
                  <rhs>"validate"  (<nt def="prod-xquery40-ValidationMode">ValidationMode<!--$idref_lang_part = xquery40- --></nt>  |  ("type"  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>))?  "{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-ValidateExpr-ValidationMode">
                  <lhs>ValidationMode</lhs>
                  <rhs>"lax"  |  "strict"</rhs>
               </prod>

               <prod id="doc-xquery40-ValidateExpr-TypeName">
                  <lhs>TypeName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ValidateExpr-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ValidateExpr-Expr">
                  <lhs>Expr</lhs>
                  <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>
            </scrap>
            <p>A <code nobreak="false">validate</code> expression can be used to validate a
        document node or an element node with respect to the <termref def="dt-issd">in-scope schema definitions</termref>, using the schema
        validation process defined in <xspecref spec="FO40" ref="xsd-validation"/>.
         The <term>effective schema</term> used for validation is the set
         of schema components contained in the 
            <termref def="dt-issd">in-scope schema definitions</termref>. The
         operand node is the result of evaluating the expression within
         the curly brackets.</p>
            <p>A <code nobreak="false">validate</code> expression returns a new node with its own identity and with no parent.
        The new node and its descendants are given <termref def="dt-type-annotation">type annotations</termref>
        that are generated by applying a validation process to the operand node. Default values
        for elements and attributes may also be generated by the validation process.</p>
            <p>If a type name is provided, and the type name is <code nobreak="false">xs:untyped</code>, 
                  no validation takes place: all elements receive the type annotation <code nobreak="false">xs:untyped</code>,
        and all attributes receive the type annotation <code nobreak="false">xs:untypedAtomic</code>. 
        If the type name is <code nobreak="false">xs:untypedAtomic</code>, the node receives the type annotation <code nobreak="false">xs:untypedAtomic</code>;
        a type error <errorref class="TY" code="0004"/> is raised if the node has element children.
         The typed value of each node is changed to be the same as its string value, as an instance of
         <code nobreak="false">xs:untypedAtomic</code>. In the case of elements the
         <code nobreak="false">nilled</code> property is set to <code nobreak="false">false</code>. The values
         of the <code nobreak="false">is-id</code> and <code nobreak="false">is-idrefs</code> properties are
          unchanged.</p>
            <p>In all other cases, the result of a <code nobreak="false">validate</code> expression is defined by reference
         to the <function>fn:xsd-validator</function> function:</p>
            <ulist>
               <item>
                  <p>The expressions <code nobreak="false">validate { <var>E</var> }</code>
               and <code nobreak="false">validate strict { <var>E</var> }</code> translate to:</p>
                  <eg xml:space="preserve"><code nobreak="false">fn:xsd-validator({'validation-mode':'strict'})(<var>E</var>) -&gt;
    if (?is-valid) then ?typed-node else error()</code></eg>
               </item>
               <item>
                  <p>The expression <code nobreak="false">validate lax { <var>E</var> }</code> translates to:</p>
                  <eg xml:space="preserve"><code nobreak="false">fn:xsd-validator({'validation-mode':'lax'})(<var>E</var>) -&gt;
    if (?is-valid) then ?typed-node else error()</code></eg>
               </item>
               <item>
                  <p>The expression <code nobreak="false">validate type <var>T</var> { <var>E</var> }</code>
               translates to:</p>
                  <eg xml:space="preserve"><code nobreak="false">fn:xsd-validator({'type':<var>T'</var>})(<var>E</var>) -&gt;
    if (?is-valid) then ?typed-node else error()</code></eg>
                  <p>where <var>T'</var> is the <code nobreak="false">xs:QName</code> value obtained by expanding <var>T</var>
               (the supplied <code nobreak="false">TypeName</code>) using the <termref def="dt-default-type-namespace-rule"/>.</p>
               </item>
               <item>
                  <p>The error reporting when <code nobreak="false">?is-valid</code> returns false is defined in more
            detail below.</p>
               </item>
            </ulist>
            <note>
               <p>The effect of these rules is that when validation succeeds, the <code nobreak="false">validate</code>
         expression returns a copy of the operand node, augmented with type annotations and expanded
         default values. When validation fails (more accurately, when the outcome of validity assessment
         is that the operand node is found to be invalid), the expression raises a dynamic error.</p>
            </note>
            <p>It is <rfc2119>recommended</rfc2119> that the call on <function>xsd-validator</function>
	     should use the default option setting <code nobreak="false">use-xsi-schema-location = false()</code>.
	     In previous versions of the specification it was <termref def="dt-implementation-defined"/> 
	        whether the validity assessment process should take account of any <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
           attributes in the tree being validated; and for backwards compatibility processors
	     <rfc2119>may</rfc2119> therefore set this option to <code nobreak="false">true</code>. This version of
	     the specification also defines more prescriptive rules for how instance-defined
	     schema locations should be handled if the processor chooses not to ignore them.</p>
            <p>The error conditions that may arise are as follows. The error codes, for backwards
         compatibility reasons, are not the same as those raised by the <code nobreak="false">xsd-validator</code>
         function.</p>
            <table border="1" role="medium">
               <caption>Error Codes Raised by the Validate Expression</caption>
               <col width="30%" span="1"/>
               <col width="70%" span="1"/>
               <thead>
                  <tr>
                     <th rowspan="1" colspan="1">Error Code</th>
                     <th rowspan="1" colspan="1">Meaning</th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Static error <errorref class="ST" code="0009"/>
                        </p>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>The processor does not provide the <term>Schema Aware Feature</term>.</p>
                     </td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Type error <errorref class="TY" code="0030"/>
                        </p>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>The result of the operand expression is not a single document 
                     or element node.</p>
                     </td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Type error <errorref class="DY" code="0061"/>
                        </p>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>The result of the operand expression is a document node
                  whose content does not consist of exactly one element node and
                  zero or more comment and processing instruction nodes.</p>
                     </td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Static error <errorref class="ST" code="0104"/>
                        </p>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>The supplied <code nobreak="false">TypeName</code> is not found in the
                  <termref def="dt-issd"/>.</p>
                     </td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Type error <errorref class="TY" code="0004"/>
                        </p>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>The specified type is <code nobreak="false">xs:untypedAtomic</code>,
                  but the operand node has element children.</p>
                     </td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Dynamic error <errorref class="DY" code="0084"/>
                        </p>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Strict validation was requested, but there is no
                  element declaration in the <termref def="dt-issd"/> whose name
                  matches the name of the operand node (or the top-level element
                  in the case where the operand node is a document node).</p>
                     </td>
                  </tr>
                  <tr>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>Dynamic error <errorref class="DY" code="0027"/>
                        </p>
                     </td>
                     <td valign="top" rowspan="1" colspan="1">
                        <p>After validation, the <code nobreak="false">validity</code> property
                  of the root element is not <code nobreak="false">valid</code>; or, after
                  lax validation, the <code nobreak="false">validity</code> property is
                  neither <code nobreak="false">valid</code> nor <code nobreak="false">notKnown</code>.</p>
                     </td>
                  </tr>
               </tbody>
            </table>
            <note diff="add" at="Issue451">
               <p>A query might take as its primary input a document conforming to schema <var>X</var>,
            and produce as its primary output a document conforming to schema <var>Y</var>.
            To be sure that the output is indeed valid against schema <var>Y</var>, the safest
            course of action is to evaluate a <code nobreak="false">validate</code> expression within
            a query module that imports schema <var>Y</var> and nothing else. Otherwise,
               if the validation occurs within a module that imports both <var>X</var>
            and <code nobreak="false">Y</code>, the outcome of validation might differ because of the
            differences between the two schemas.</p>
            </note>
         </div2>
         <div2 id="id-extension-expressions" role="xquery">
            <head>Extension Expressions</head>
            <changes>
               <change issue="1981" PR="1982" date="2024-05-08">
               Whitespace is now required after the opening <code nobreak="false">(#</code> of a pragma. This
               is an incompatible change, made to ensure that an expression such as <code nobreak="false">error(#err:XPTY0004)</code>
               can be parsed as a function call taking a QName literal as its argument value.
            </change>
            </changes>
            <p>
               <termdef id="dt-extension-expression" term="extension expression">An <term>extension expression</term> is an expression whose semantics are
<termref def="dt-implementation-defined">implementation-defined</termref>.</termdef> Typically a particular extension will be recognized
by some implementations and not by others. The syntax is designed so that
extension expressions can be successfully parsed by all implementations, and
so that fallback behavior can be defined for implementations that do not
recognize a particular extension.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ExtensionExpr">
                  <lhs>ExtensionExpr</lhs>
                  <rhs>
                     <nt def="prod-xquery40-Pragma">Pragma<!--$idref_lang_part = xquery40- --></nt>+  "{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>

               <prod id="doc-xquery40-ExtensionExpr-Pragma">
                  <lhs>Pragma</lhs>
                  <rhs>"(#"  <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-PragmaContents">PragmaContents<!--$idref_lang_part = xquery40- --></nt>)?  "#)"</rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-ExtensionExpr-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ExtensionExpr-PragmaContents">
                  <lhs>PragmaContents</lhs>
                  <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* '#)' Char*))</rhs>
               </prod>

               <prod id="doc-xquery40-ExtensionExpr-Char">
                  <lhs>Char</lhs>
                  <rhs>
                     <xnt ref="NT-Char" spec="XML">[http://www.w3.org/TR/REC-xml#NT-Char]</xnt>
                  </rhs>
                  <com>
                     <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-ExtensionExpr-Expr">
                  <lhs>Expr</lhs>
                  <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>
            </scrap>
            <p>An extension expression consists of one or more <term>pragmas</term>, 
            followed by an optional expression (the <term>associated expression</term>). <termdef term="pragma" id="dt-pragma">A <term>pragma</term> is denoted by the delimiters <code nobreak="false">(#</code> and <code nobreak="false">#)</code>, 
               and consists of an identifying EQName followed by <termref def="dt-implementation-defined">implementation-defined</termref> content.</termdef>
            </p>
            <p>The identifying EQName is expanded using the <termref def="dt-no-namespace-rule"/>.</p>
            <note>
               <p>If the EQName is an unprefixed NCName, it is interpreted as a name in no namespace, and the pragma is therefore ignored.</p>
            </note>
            <p>The content of a pragma may consist of any string of characters 
            that does not contain the ending delimiter <code nobreak="false">#)</code>.</p>
            <p>Each implementation recognizes an <termref def="dt-implementation-defined">implementation-defined</termref> set
of namespace URIs used to denote pragmas.</p>
            <p>If the namespace URI of a pragma’s <termref def="dt-expanded-qname">expanded QName</termref> 
is not recognized by the implementation as a pragma namespace, 
 or if the name is in no namespace, 
then the pragma is ignored. If all the pragmas in an <nt def="doc-xquery40-ExtensionExpr">ExtensionExpr<!--$spec = xquery40--></nt> are ignored, then the
value of the <nt def="doc-xquery40-ExtensionExpr">ExtensionExpr<!--$spec = xquery40--></nt> is the value of the 
 

associated expression; if no associated expression is provided,  a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0079"/>.
</p>
            <p>If an implementation recognizes the namespace of one or more
pragmas in an <nt def="doc-xquery40-ExtensionExpr">ExtensionExpr<!--$spec = xquery40--></nt>, then the
value of the <nt def="doc-xquery40-ExtensionExpr">ExtensionExpr<!--$spec = xquery40--></nt>, including its
error behavior, is <termref def="dt-implementation-defined">implementation-defined</termref>. For
example, an implementation that recognizes the namespace of a pragma’s
<termref def="dt-expanded-qname">expanded QName</termref>, but does
not recognize the local part of the name, might choose either to raise
an error or to ignore the pragma.</p>
            <p>It is a <termref def="dt-static-error">static error</termref>
               <errorref code="0013" class="ST"/> if an implementation recognizes a pragma but determines
that its content is invalid.</p>
            <p>If an implementation recognizes a
pragma, it must report any static errors in the following expression
even if it will not evaluate that expression.</p>
            <note>
               <p>The following examples illustrate three ways in
which extension expressions might be used.</p>
               <ulist>
                  <item>
                     <p>A pragma can be used to furnish a hint for how to evaluate the
following expression, without actually changing the result.
For example:</p>
                     <eg role="parse-test" xml:space="preserve">declare namespace exq = "http://example.org/XQueryImplementation";
(# exq:use-index #) {
  $bib/book/author[name = 'Berners-Lee']
}
</eg>
                     <p>An implementation that recognizes the <code nobreak="false">exq:use-index</code> pragma might use an
index to evaluate the  expression that follows. An implementation that
does not recognize this pragma would evaluate the expression in its normal
way.</p>
                  </item>
                  <item>
                     <p>A pragma might be used to modify the semantics of the following
expression in ways that would not (in the absence of the pragma) be
conformant with this specification. For example, a pragma might be used to
permit comparison of <code nobreak="false">xs:duration</code> values using implementation-defined
semantics (this would normally be an error). Such changes to the language
semantics must be scoped to the <termref def="dt-enclosed-expression">enclosed expression</termref> following the pragma.</p>
                  </item>
                  <item>
                     <p>A pragma might contain syntactic constructs that are
evaluated in place of the following expression. In this case, the
following expression itself (if it is present) provides a fallback for use by
implementations that do not recognize the pragma. For example:</p>
                     <eg role="parse-test" xml:space="preserve">declare namespace exq = "http://example.org/XQueryImplementation";

for $x in (# exq:distinct //city by @country #) {
  //city[not(@country = preceding::city/@country)]
}
return f:show-city($x)
</eg>
                     <p>Here an implementation that recognizes the pragma will return the result of
evaluating the proprietary syntax <code nobreak="false">exq:distinct //city by
@country</code>,
while an implementation that does not recognize the pragma will instead
return the result of the expression <code role="parse-test" nobreak="false">//city[not(@country =
preceding::city/@country)]</code>. If no fallback expression is required, or
if none is feasible, then the expression between the curly brackets may be
omitted, in which case implementations that do not recognize the pragma will
raise a <termref def="dt-static-error">static error</termref>.</p>
                  </item>
               </ulist>
            </note>
         </div2>
      </div1>
      <div1 role="xquery" id="id-query-prolog">
         <head role="xquery">Modules and Prologs</head>
         <scrap headstyle="show">
            <prod id="doc-xquery40-Module">
               <lhs>Module</lhs>
               <rhs>
                  <nt def="prod-xquery40-VersionDecl">VersionDecl<!--$idref_lang_part = xquery40- --></nt>?  (<nt def="prod-xquery40-LibraryModule">LibraryModule<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MainModule">MainModule<!--$idref_lang_part = xquery40- --></nt>)</rhs>
            </prod>

            <prod id="doc-xquery40-Module-VersionDecl">
               <lhs>VersionDecl</lhs>
               <rhs>"xquery"  (("encoding"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)  |  ("version"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  ("encoding"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)?))  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-LibraryModule">
               <lhs>LibraryModule</lhs>
               <rhs>
                  <nt def="prod-xquery40-ModuleDecl">ModuleDecl<!--$idref_lang_part = xquery40- --></nt>
                  <nt def="prod-xquery40-Prolog">Prolog<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-ModuleDecl">
               <lhs>ModuleDecl</lhs>
               <rhs>"module"  "namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-Prolog">
               <lhs>Prolog</lhs>
               <rhs>((<nt def="prod-xquery40-DefaultNamespaceDecl">DefaultNamespaceDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Setter">Setter<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NamespaceDecl">NamespaceDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Import">Import<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>)*  ((<nt def="prod-xquery40-ContextValueDecl">ContextValueDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-VarDecl">VarDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionDecl">FunctionDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ItemTypeDecl">ItemTypeDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NamedRecordTypeDecl">NamedRecordTypeDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-OptionDecl">OptionDecl<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
            </prod>

            <prod id="doc-xquery40-Module-DefaultNamespaceDecl">
               <lhs>DefaultNamespaceDecl</lhs>
               <rhs>"declare"  "fixed"?  "default"  ("element"  |  "function")  "namespace"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-Setter">
               <lhs>Setter</lhs>
               <rhs>
                  <nt def="prod-xquery40-BoundarySpaceDecl">BoundarySpaceDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DefaultCollationDecl">DefaultCollationDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BaseURIDecl">BaseURIDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ConstructionDecl">ConstructionDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-OrderingModeDecl">OrderingModeDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EmptyOrderDecl">EmptyOrderDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CopyNamespacesDecl">CopyNamespacesDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DecimalFormatDecl">DecimalFormatDecl<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-BoundarySpaceDecl">
               <lhs>BoundarySpaceDecl</lhs>
               <rhs>"declare"  "boundary-space"  ("preserve"  |  "strip")</rhs>
            </prod>

            <prod id="doc-xquery40-Module-DefaultCollationDecl">
               <lhs>DefaultCollationDecl</lhs>
               <rhs>"declare"  "default"  "collation"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-BaseURIDecl">
               <lhs>BaseURIDecl</lhs>
               <rhs>"declare"  "base-uri"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-ConstructionDecl">
               <lhs>ConstructionDecl</lhs>
               <rhs>"declare"  "construction"  ("strip"  |  "preserve")</rhs>
            </prod>

            <prod id="doc-xquery40-Module-OrderingModeDecl">
               <lhs>OrderingModeDecl</lhs>
               <rhs>"declare"  "ordering"  ("ordered"  |  "unordered")</rhs>
            </prod>

            <prod id="doc-xquery40-Module-EmptyOrderDecl">
               <lhs>EmptyOrderDecl</lhs>
               <rhs>"declare"  "default"  "order"  "empty"  ("greatest"  |  "least")</rhs>
            </prod>

            <prod id="doc-xquery40-Module-CopyNamespacesDecl">
               <lhs>CopyNamespacesDecl</lhs>
               <rhs>"declare"  "copy-namespaces"  <nt def="prod-xquery40-PreserveMode">PreserveMode<!--$idref_lang_part = xquery40- --></nt>  ","  <nt def="prod-xquery40-InheritMode">InheritMode<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-DecimalFormatDecl">
               <lhs>DecimalFormatDecl</lhs>
               <rhs>"declare"  (("decimal-format"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>)  |  ("default"  "decimal-format"))  (<nt def="prod-xquery40-DFPropertyName">DFPropertyName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
            </prod>

            <prod id="doc-xquery40-Module-NamespaceDecl">
               <lhs>NamespaceDecl</lhs>
               <rhs>"declare"  "namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-Import">
               <lhs>Import</lhs>
               <rhs>
                  <nt def="prod-xquery40-SchemaImport">SchemaImport<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ModuleImport">ModuleImport<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-SchemaImport">
               <lhs>SchemaImport</lhs>
               <rhs>"import"  "schema"  <nt def="prod-xquery40-SchemaPrefix">SchemaPrefix<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>  ("at"  (<nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt> ++ ","))?</rhs>
            </prod>

            <prod id="doc-xquery40-Module-ModuleImport">
               <lhs>ModuleImport</lhs>
               <rhs>"import"  "module"  ("namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "=")?  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>  ("at"  (<nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt> ++ ","))?</rhs>
            </prod>

            <prod id="doc-xquery40-Module-Separator">
               <lhs>Separator</lhs>
               <rhs>";"</rhs>
            </prod>

            <prod id="doc-xquery40-Module-ContextValueDecl">
               <lhs>ContextValueDecl</lhs>
               <rhs>"declare"  "context"  (("value"  ("as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?)  |  ("item"  ("as"  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>)?))  ((":="  <nt def="prod-xquery40-VarValue">VarValue<!--$idref_lang_part = xquery40- --></nt>)  |  ("external"  (":="  <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$idref_lang_part = xquery40- --></nt>)?))</rhs>
            </prod>

            <prod id="doc-xquery40-Module-VarDecl">
               <lhs>VarDecl</lhs>
               <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "variable"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  ((":="  <nt def="prod-xquery40-VarValue">VarValue<!--$idref_lang_part = xquery40- --></nt>)  |  ("external"  (":="  <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$idref_lang_part = xquery40- --></nt>)?))</rhs>
            </prod>

            <prod id="doc-xquery40-Module-FunctionDecl">
               <lhs>FunctionDecl</lhs>
               <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "function"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "("  <nt def="prod-xquery40-ParamListWithDefaults">ParamListWithDefaults<!--$idref_lang_part = xquery40- --></nt>?  ")"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  (<nt def="prod-xquery40-FunctionBody">FunctionBody<!--$idref_lang_part = xquery40- --></nt>  |  "external")</rhs>
               <com>
                  <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
               </com>
            </prod>

            <prod id="doc-xquery40-Module-ItemTypeDecl">
               <lhs>ItemTypeDecl</lhs>
               <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "type"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "as"  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-NamedRecordTypeDecl">
               <lhs>NamedRecordTypeDecl</lhs>
               <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "record"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "("  (<nt def="prod-xquery40-ExtendedFieldDeclaration">ExtendedFieldDeclaration<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"</rhs>
            </prod>

            <prod id="doc-xquery40-Module-OptionDecl">
               <lhs>OptionDecl</lhs>
               <rhs>"declare"  "option"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-MainModule">
               <lhs>MainModule</lhs>
               <rhs>
                  <nt def="prod-xquery40-Prolog">Prolog<!--$idref_lang_part = xquery40- --></nt>
                  <nt def="prod-xquery40-QueryBody">QueryBody<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-QueryBody">
               <lhs>QueryBody</lhs>
               <rhs>
                  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>
               </rhs>
            </prod>

            <prod id="doc-xquery40-Module-Expr">
               <lhs>Expr</lhs>
               <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
            </prod>
         </scrap>
         <p>A query can be assembled from one or more fragments called <term>modules</term>. <termdef term="module" id="dt-module">A <term>module</term> is a fragment of XQuery code that conforms
      to the <nt def="doc-xquery40-Module">Module<!--$spec = xquery40--></nt> grammar and can independently undergo the <termref def="dt-static-analysis">static analysis phase</termref> described in <specref ref="id-expression-processing"/>. Each module is either a <termref def="dt-main-module">main
        module</termref> or a <termref def="dt-library-module">library
    module</termref>.</termdef>
         </p>
         <p>
            <termdef id="dt-main-module" term="main module">A <term>main module</term> consists of a
        <termref def="dt-prolog">Prolog</termref> followed by a <termref def="dt-queryBody">Query
        Body</termref>.</termdef> A query has exactly one main module. In a main module, the
      <termref def="dt-queryBody">Query Body</termref> is evaluated with respect to the static and
    dynamic contexts of the main module in which it is found, and its value is the result of the
    query.</p>
         <p>
            <termdef id="dt-library-module" term="library module">A module that does not contain a <termref def="dt-queryBody">Query Body</termref> is called a <term>library module</term>. A library
      module consists of a <termref def="dt-module-declaration">module declaration</termref>
      followed by a <termref def="dt-prolog">Prolog</termref>.</termdef> A library module cannot be
    evaluated directly; instead, it provides function and variable declarations that can be imported
    into other modules.</p>
         <p>The XQuery syntax does not allow a <termref def="dt-module">module</termref> to contain both a
      <termref def="dt-module-declaration">module declaration</termref> and a <termref def="dt-queryBody">Query Body</termref>.</p>
         <p>
            <termdef id="dt-prolog" term="Prolog">A <term>Prolog</term> is a series of declarations and
      imports that define the processing environment for the <termref def="dt-module">module</termref> that contains the Prolog.</termdef> Each declaration or import is followed
    by a semicolon. A Prolog is organized into two parts. </p>
         <p>The first part of the Prolog consists of setters, imports, namespace declarations, and default
    namespace declarations. <termdef term="setter" id="dt-setter">
               <term>Setters</term> are
      declarations that set the value of some property that affects query processing, such as
      construction mode or default collation.</termdef> Namespace declarations and
    default namespace declarations affect the interpretation of <termref def="dt-qname">lexical
      QNames</termref> within the query. Imports are used to import definitions from schemas and
    modules. <termdef term="target namespace" id="dt-target-namespace"> The <term>target
        namespace</term> of a module is the namespace of the objects (such as elements or functions)
      that it defines. </termdef>
         </p>
         <p>The second part of the Prolog consists of declarations of variables, functions, and options.
    These declarations appear at the end of the Prolog because they may be affected by declarations
    and imports in the first part of the Prolog.</p>
         <p>
            <termdef id="dt-queryBody" term="query body">The <term>Query Body</term>, if present, consists
      of an expression that defines the result of the query.</termdef> Evaluation of expressions is
    described in <specref ref="id-expressions"/>. A module can be evaluated only if it has a Query
    Body.</p>
         <div2 id="id-version-declaration">
            <head>Version Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-VersionDecl">
                  <lhs>VersionDecl</lhs>
                  <rhs>"xquery"  (("encoding"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)  |  ("version"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  ("encoding"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)?))  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-VersionDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-VersionDecl-Separator">
                  <lhs>Separator</lhs>
                  <rhs>";"</rhs>
               </prod>
            </scrap>
            <p>
               <termdef term="version declaration" id="dt-version-declaration">
      A <term>version declaration</term> can identify the applicable
      XQuery syntax and semantics for a <termref def="dt-module">module</termref>, as well as its
      encoding.</termdef>
            </p>
            <p>
               <termdef id="dt-version-number" term="XQuery version number">An <term>XQuery version number</term> 
        consists of two integers, referred to as the 
        <term>major version number</term> and the  <term>minor version number</term>.</termdef>
            </p>
            <p>The version number is written as a <code nobreak="false">StringLiteral</code> following the <code nobreak="false">version</code>
      keyword, and in a conformant XQuery 4.0 query it <rfc2119>must</rfc2119> match the regular expression 
      <code nobreak="false">[1-9][0-9]*\.[0-9]</code>: for example <code nobreak="false">"4.0"</code>. The major version is the integer 
        preceding the dot (which must be written without any leading zero); the minor version is the
      integer after the dot (which must be a single digit).</p>
            <note>
               <p>XQuery 1.0 and 3.0 allowed the version number to be any string; XQuery 3.1 constrained it
        to consist of two integers separated by a dot. This left it unclear, for example,
        whether "3.01" was the same version number as "3.1", or whether "3.10" represented a higher version
        than "3.2". In 4.0 the rules have therefore been made stricter, to avoid any ambiguity.</p>
            </note>
            <p>If the version declaration is not
      present or the version is not included in the declaration, an
      XQuery 4.0 processor assumes a version of "4.0", unless configured otherwise using
      some external mechanism.</p>
            <p>The version number "4.0" indicates the intent that the module
      be processed by an <termref def="dt-xquery-40-processor">XQuery
        4.0 processor</termref>.</p>
            <p>An XQuery 4.0 processor must accept a module in which the version number is given as
      "1.0", "3.0", or "3.1". It is then <termref def="dt-implementation-defined"/> whether
      the module is processed using the syntax and semantics of the XQuery 4.0 specification, or the rules
      of the relevant earlier version. For example, if a query module specifies version <code nobreak="false">"3.0"</code>
      but contains a call to the <code nobreak="false">parse-html</code> function, the processor at its option can
      either raise an error, or process the function call according to the XQuery 4.0 specification.</p>
            <p>The XQuery 4.0 specification does not attempt to define the semantics of a query in which
      different modules use different version numbers. One approach is to process all modules as if
      they specified version "4.0". Another approach (which may be appropriate if modules
      are separately compiled) is to process each module using its own version number; but it is then
      <termref def="dt-implementation-defined"/> what happens if (say) a 3.1 module imports a 
      4.0 library module that declares a function with a signature that 3.1 does not recognize.</p>
            <p>A conformant XQuery 4.0 processor <rfc2119>may</rfc2119> raise an error if the version number is anything
      other than "1.0", "3.0", "3.1", or "4.0". If the processor does not raise an error, the effect of such
      a query is <termref def="dt-implementation-defined"/>.</p>
            <note>
               <p>The effect of this rule is to permit the use of non-standard version numbers to
        label non-standard extensions of the XQuery language. It also leaves flexibility as
        to how an XQuery 4.0 processor should handle future version numbers such as "4.1",
        or version numbers such as "1" or "3.00" that were permitted by earlier XQuery
        specifications.</p>
            </note>
            <p>If a query is rejected because of a version mismatch with the processor, a static error  
      <errorref code="0031" class="ST"/> must be raised.</p>
            <p>
               <termdef term="encoding declaration" id="dt-encoding-declaration">If present, a version
        declaration may optionally include an <term>encoding declaration</term>. The value of the
        string literal following the keyword <code nobreak="false">encoding</code> is an encoding name, and must
        conform to the definition of <code nobreak="false">EncName</code> specified in <bibref ref="XML"/>
                  <errorref code="0087" class="ST"/>. The purpose of an encoding declaration is to allow the writer of
        a query to provide a string that indicates how the query is encoded, such as
          <code nobreak="false">"UTF-8"</code>, <code nobreak="false">"UTF-16"</code>, or <code nobreak="false">"US-ASCII"</code>.</termdef> Since
      the encoding of a query may change as the query moves from one environment to another, there
      can be no guarantee that the encoding declaration is correct.</p>
            <p>The handling of an encoding declaration is <termref def="dt-implementation-dependent">implementation-dependent</termref>. If an implementation has <emph>a priori</emph>
      knowledge of the encoding of a query, it may use this knowledge and disregard the encoding
      declaration. The semantics of a query are not affected by the presence or absence of an
      encoding declaration.</p>
            <p>If a version declaration is present, no <nt def="doc-xquery40-Comment">Comment<!--$spec = xquery40--></nt> may occur before the
      end of the version declaration. If such a <nt def="doc-xquery40-Comment">Comment<!--$spec = xquery40--></nt> is present, the
      result is <termref def="dt-implementation-dependent">implementation-dependent</termref>; an
      implementation may raise an implementation-dependent static error, or ignore the comment. <note>
                  <p>The effect of a <code nobreak="false">Comment</code> before the end of a version declaration is
          implementation-dependent because it may suppress query processing by interfering with
          detection of the encoding declaration.</p>
               </note>
            </p>
            <p>The following examples illustrate version declarations:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">xquery version "3.1";</eg>
            <eg role="frag-prolog-parse-test" xml:space="preserve">xquery version "4.0" encoding "UTF-8";</eg>
         </div2>
         <div2 id="id-module-declaration">
            <head>Module Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ModuleDecl">
                  <lhs>ModuleDecl</lhs>
                  <rhs>"module"  "namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ModuleDecl-URILiteral">
                  <lhs>URILiteral</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ModuleDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-ModuleDecl-Separator">
                  <lhs>Separator</lhs>
                  <rhs>";"</rhs>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-module-declaration" term="module declaration">A <term>module
          declaration</term> serves to identify a <termref def="dt-module">module</termref> as a
          <termref def="dt-library-module">library module</termref>. A module declaration begins
        with the keyword <code nobreak="false">module</code> and contains a namespace prefix and a <nt def="prod-xquery40-URILiteral">URILiteral<!--$spec = xquery40--></nt>.</termdef> The URILiteral must be of nonzero length
        <errorref class="ST" code="0088"/>. The URILiteral identifies the <termref def="dt-target-namespace">target namespace</termref> of the library module, which is the
      namespace for all variables and functions exported by the library module. The name of every
      variable and function declared in a library module must have a namespace URI that is the same
      as the target namespace of the module; otherwise a <termref def="dt-static-error">static
        error</termref> is raised <errorref class="ST" code="0048"/>. The (prefix,URI) pair is added
      to the set of <termref def="dt-static-namespaces">statically known namespaces</termref>. </p>
            <p>The namespace prefix specified in a module declaration must not be <code nobreak="false">xml</code> or
        <code nobreak="false">xmlns</code>
               <errorref class="ST" code="0070"/>, and must not be the same as any namespace prefix bound in
      the same module by a <termref def="dt-schema-import">schema import</termref>, by a <termref def="dt-namespace-declaration">namespace declaration</termref>, or by a <termref def="dt-module-import">module import</termref> with a different target namespace <errorref class="ST" code="0033"/>.</p>
            <p>Any <termref def="dt-module">module</termref> may import one or more library modules by means
      of a <termref def="dt-module-import">module import</termref> that specifies the target
      namespace of the library modules to be imported. When a module imports one or more library
      modules, the variables and functions declared in the imported modules are added to the
        <termref def="dt-static-context">static context</termref> and (where applicable) to the
        <termref def="dt-dynamic-context">dynamic context</termref> of the importing module.</p>
            <p>The following is an example of a module declaration:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">module namespace gis = "http://example.org/gis-functions";</eg>
         </div2>
         <div2 id="id-boundary-space-decls">
            <head>Boundary-space Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-BoundarySpaceDecl">
                  <lhs>BoundarySpaceDecl</lhs>
                  <rhs>"declare"  "boundary-space"  ("preserve"  |  "strip")</rhs>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-boundary-space-decl" term="boundary-space declaration">A <term>boundary-space
          declaration</term> sets the <termref def="dt-boundary-space-policy">boundary-space
          policy</termref> in the <termref def="dt-static-context">static context</termref>,
        overriding any implementation-defined default. Boundary-space policy controls whether
          <termref def="dt-boundary-whitespace">boundary whitespace</termref> is preserved by
        element constructors during processing of the query.</termdef> If boundary-space policy is
        <code nobreak="false">preserve</code>, boundary whitespace is preserved. If boundary-space policy is
        <code nobreak="false">strip</code>, boundary whitespace is stripped (deleted). A further discussion of
      whitespace in constructed elements can be found in <specref ref="id-whitespace"/>.</p>
            <p>The following example illustrates a boundary-space declaration:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare boundary-space preserve;</eg>
            <p>If a Prolog contains more than one boundary-space declaration, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0068"/>.</p>
         </div2>
         <div2 id="id-default-collation-declaration">
            <head>Default Collation Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-DefaultCollationDecl">
                  <lhs>DefaultCollationDecl</lhs>
                  <rhs>"declare"  "default"  "collation"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-DefaultCollationDecl-URILiteral">
                  <lhs>URILiteral</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-DefaultCollationDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <termdef term="default collation declaration" id="dt-default-collation-decl">A <term>default
          collation declaration</term> sets the value of the <termref def="dt-def-collation">default
          collation</termref> in the <termref def="dt-static-context">static context</termref>,
        overriding any implementation-defined default.</termdef> The default collation is the
      collation that is used by functions and operators that require a collation if no other
      collation is specified. For example, the <code nobreak="false">gt</code> operator on strings is defined by a
      call to the <function>fn:compare</function> function, which takes an optional collation parameter.
      Since the <code nobreak="false">gt</code> operator does not specify a collation, the <function>fn:compare</function>
      function implements <code nobreak="false">gt</code> by using the default collation.</p>
            <p>If neither the implementation nor the Prolog specifies a default collation, the Unicode
      codepoint collation (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>)
      is used. </p>
            <p>The following example illustrates a default collation declaration:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare default collation "http://example.org/languages/Icelandic";</eg>
            <p>If a default collation declaration specifies a collation by a relative URI, that relative URI
      is <termref def="dt-resolve-relative-uri">resolved to an absolute URI</termref> using the
        <termref def="dt-static-base-uri">Static Base URI</termref>. If a Prolog contains more than
      one default collation declaration, or the value specified by a default collation declaration
      (after resolution of a relative URI, if necessary) is not present in <termref def="dt-static-collations">statically known collations</termref>, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0038"/>.</p>
         </div2>
         <div2 id="id-base-uri-decl">
            <head>Base URI Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-BaseURIDecl">
                  <lhs>BaseURIDecl</lhs>
                  <rhs>"declare"  "base-uri"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-BaseURIDecl-URILiteral">
                  <lhs>URILiteral</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-BaseURIDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-base-uri-decl" term="base URI declaration">A <term>base URI declaration</term>
        specifies the <termref def="dt-static-base-uri">Static Base URI</termref> property. The
          <termref def="dt-static-base-uri">Static Base URI</termref> property is used when
        resolving relative URI references.</termdef> For example, the <termref def="dt-static-base-uri">Static Base URI</termref> property is used when resolving relative
      references for <termref def="dt-module-import">module import</termref> and for the
        <function>fn:doc</function> function.</p>
            <note>
               <p>As discussed in the definition of <termref def="dt-static-base-uri">Static Base
          URI</termref>, if there is no base URI declaration, or if the value of the declaration is
        a relative URI reference, then the value of the Static Base URI may depend on the location
        of the query, and it is permissible for this to vary between the static analysis phase and
        the dynamic evaluation phase.</p>
            </note>
            <p>The following is an example of a base URI declaration:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare base-uri "http://example.org";</eg>
            <p>If a Prolog contains more than one base URI declaration, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0032"/>.</p>
            <p>In the terminology of <bibref ref="RFC3986"/> Section 5.1, the URILiteral of the base URI
      declaration is considered to be a “base URI embedded in content”. If no base URI declaration
      is present, <termref def="dt-static-base-uri">Static Base URI</termref> property is
      established according to the principles outlined in <bibref ref="RFC3986"/> Section
      5.1—that is, it defaults first to the base URI of the encapsulating entity, then to the
      URI used to retrieve the entity, and finally to an implementation-defined default. If the
      URILiteral in the base URI declaration is a relative URI, then it is made absolute by
      resolving it with respect to this same hierarchy. For example, if the URILiteral in the base
      URI declaration is <code nobreak="false">../data/</code>, and the query is contained in a file whose URI is
        <code nobreak="false">file:///C:/temp/queries/query.xq</code>, then the <termref def="dt-static-base-uri">Static Base URI</termref> property is <code nobreak="false">file:///C:/temp/data/</code>.</p>
            <p>It is not intrinsically an error if this process fails to establish an absolute base URI;
      however, the <termref def="dt-static-base-uri">Static Base URI</termref> property is then
        <xtermref spec="DM40" ref="dt-absent"/>
               <errorref class="ST" code="0001"/>. When the <termref def="dt-static-base-uri">Static Base
        URI</termref> property is <xtermref spec="DM40" ref="dt-absent"/>, any attempt to use its
      value to <termref def="dt-resolve-relative-uri">resolve a relative URI reference</termref>
      will result in an error <errorref class="ST" code="0001"/>. </p>
         </div2>
         <div2 id="id-construction-declaration">
            <head>Construction Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ConstructionDecl">
                  <lhs>ConstructionDecl</lhs>
                  <rhs>"declare"  "construction"  ("strip"  |  "preserve")</rhs>
               </prod>
            </scrap>
            <p>
               <termdef term="construction declaration" id="dt-construction-decl">A <term>construction
          declaration</term> sets the <termref def="dt-construction-mode">construction
          mode</termref> in the <termref def="dt-static-context">static context</termref>,
        overriding any implementation-defined default.</termdef> The construction mode governs the
      behavior of element and document node constructors. If construction mode is
        <code nobreak="false">preserve</code>, the type of a constructed element node is <code nobreak="false">xs:anyType</code>,
      and all attribute and element nodes copied during node construction retain their original
      types. If construction mode is <code nobreak="false">strip</code>, the type of a constructed element node is
        <code nobreak="false">xs:untyped</code>; all element nodes copied during node construction receive the type
        <code nobreak="false">xs:untyped</code>, and all attribute nodes copied during node construction receive the
      type <code nobreak="false">xs:untypedAtomic</code>.</p>
            <p>The following example illustrates a construction declaration:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare construction strip;</eg>
            <p>If a Prolog specifies more than one construction declaration, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0067"/>.</p>
         </div2>
         <div2 id="id-default-ordering-decl">
            <head>Ordering Mode Declaration</head>
            <changes>
               <change issue="1339" PR="1342" date="2024-09-03">
               The ordering mode declaration is retained for
               backwards compatibility reasons, but in XQuery 4.0 it is deprecated and has no useful effect.
       </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-OrderingModeDecl">
                  <lhs>OrderingModeDecl</lhs>
                  <rhs>"declare"  "ordering"  ("ordered"  |  "unordered")</rhs>
               </prod>
            </scrap>
            <p>
      The ordering mode declaration is retained from earlier XQuery versions,
      but in XQuery 4.0 it is deprecated and has no effect.</p>
            <note>
               <p>That is to say, XQuery 4.0 always operates as if ordering mode were set to <code nobreak="false">ordered</code>
    in earlier versions.</p>
            </note>
            <p>If a Prolog contains more than one ordering mode declaration, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0065"/>.</p>
         </div2>
         <div2 id="id-empty-order-decl">
            <head>Empty Order Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-EmptyOrderDecl">
                  <lhs>EmptyOrderDecl</lhs>
                  <rhs>"declare"  "default"  "order"  "empty"  ("greatest"  |  "least")</rhs>
               </prod>
            </scrap>
            <p>
               <termdef term="empty order declaration" id="dt-empty-order-decl">An <term>empty order
          declaration</term> sets the <termref def="dt-default-empty-order">default order for empty
          sequences</termref> in the <termref def="dt-static-context">static context,</termref>
        overriding any implementation-defined default. This declaration controls the processing of
        empty sequences and <code nobreak="false">NaN</code> values as ordering keys in an <code nobreak="false">order by</code>
        clause in a FLWOR expression.</termdef> An individual <code nobreak="false">order by</code> clause may
      override the default order for empty sequences by specifying <code nobreak="false">empty greatest</code> or
        <code nobreak="false">empty least</code>.</p>
            <p>The following example illustrates an empty order declaration:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare default order empty least;</eg>
            <p>If a Prolog contains more than one empty order declaration, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0069"/>.</p>
         </div2>
         <div2 id="id-copy-namespaces-decl">
            <head>Copy-Namespaces Declaration</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-CopyNamespacesDecl">
                  <lhs>CopyNamespacesDecl</lhs>
                  <rhs>"declare"  "copy-namespaces"  <nt def="prod-xquery40-PreserveMode">PreserveMode<!--$idref_lang_part = xquery40- --></nt>  ","  <nt def="prod-xquery40-InheritMode">InheritMode<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-CopyNamespacesDecl-PreserveMode">
                  <lhs>PreserveMode</lhs>
                  <rhs>"preserve"  |  "no-preserve"</rhs>
               </prod>

               <prod id="doc-xquery40-CopyNamespacesDecl-InheritMode">
                  <lhs>InheritMode</lhs>
                  <rhs>"inherit"  |  "no-inherit"</rhs>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-copy-namespaces-decl" term="copy-namespaces declaration">A
          <term>copy-namespaces declaration</term> sets the value of <termref def="dt-copy-namespaces-mode">copy-namespaces mode</termref> in the <termref def="dt-static-context">static context</termref>, overriding any implementation-defined
        default. Copy-namespaces mode controls the namespace bindings that are assigned when an
        existing element node is copied by an element constructor or document constructor.</termdef>
      Handling of namespace bindings by element constructors is described in <specref ref="id-element-constructor"/>.</p>
            <p>The following example illustrates a copy-namespaces declaration:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare copy-namespaces preserve, no-inherit;</eg>
            <p>If a Prolog contains more than one copy-namespaces declaration, a <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0055"/>.</p>
         </div2>
         <div2 id="id-decimal-format-decl">
            <head>Decimal Format Declaration</head>
            <changes>
               <change issue="1048" PR="1250" date="2024-06-03">
         Several decimal format properties, including minus sign, exponent separator, percent, and per-mille,
         can now be rendered as arbitrary strings rather than being confined to a single
         character.
      </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-DecimalFormatDecl">
                  <lhs>DecimalFormatDecl</lhs>
                  <rhs>"declare"  (("decimal-format"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>)  |  ("default"  "decimal-format"))  (<nt def="prod-xquery40-DFPropertyName">DFPropertyName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
               </prod>

               <prod id="doc-xquery40-DecimalFormatDecl-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-DecimalFormatDecl-DFPropertyName">
                  <lhs>DFPropertyName</lhs>
                  <rhs>"decimal-separator"  |  "grouping-separator"  |  "infinity"  |  "minus-sign"  |  "NaN"  |  "percent"  |  "per-mille"  |  "zero-digit"  |  "digit"  |  "pattern-separator"  |  "exponent-separator"</rhs>
               </prod>

               <prod id="doc-xquery40-DecimalFormatDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-decimal-format-decl" term="decimal-format         declaration">A <term>decimal format
          declaration</term> adds a decimal format to the <termref def="dt-static-decimal-formats">statically known decimal formats</termref>, which define the properties used to format
        numbers using the <code nobreak="false">fn:format-number()</code> function</termdef>, as described in
      <bibref ref="xpath-functions-40"/>. 
      
      If the form <code nobreak="false">decimal-format EQName</code> is used, then the declaration 
        defines the properties of the decimal format whose name is <code nobreak="false">EQName</code>, while the form <code nobreak="false">default decimal-format</code> 
        defines the properties of the unnamed decimal format. The declaration contains a set of 
        (<code nobreak="false">DFPropertyName</code>, <code nobreak="false">StringLiteral</code>) pairs, where the <code nobreak="false">DFPropertyName</code> is the name 
        of the property and the <code nobreak="false">StringLiteral</code> is its value. The valid values and default values for each 
        property are defined in <termref def="dt-static-decimal-formats">statically known decimal formats</termref>.
      </p>
            <p>If a format declares no properties, default values are
      used for all properties.</p>
            <p>Error conditions are defined as follows:</p>
            <ulist>
               <item>
                  <p>It is a <termref def="dt-static-error">static error</termref> for a query prolog to contain
        two decimal format declarations with the same name, or to contain two default decimal format
        declarations <errorref class="ST" code="0111"/>.</p>
               </item>
               <item>
                  <p>It is a <termref def="dt-static-error">static
        error</termref> for a decimal format declaration to define the same property more than once
        <errorref class="ST" code="0114"/>.</p>
               </item>
               <item>
                  <p>It is a <termref def="dt-static-error">static
        error</termref> for a decimal format declaration to specify a value that is not valid for a
        given property, as described in <termref def="dt-static-decimal-formats">statically known
          decimal formats</termref>
                     <errorref class="ST" code="0097"/>.</p>
               </item>
               <item>
                  <p>It is a <termref def="dt-static-error">static
        error</termref> if, for any named or unnamed decimal format, the properties identifying
        <term>marker</term> characters to be used in a picture string do identify distinct values <errorref class="ST" code="0098"/>.</p>
                  <p>The following properties identify <term>marker</term> characters used in a picture string:
        <termref def="id-static-decimal-format-decimal-separator">decimal-separator</termref>, 
        <termref def="id-static-decimal-format-exponent-separator">exponent-separator</termref>,
        <termref def="id-static-decimal-format-grouping-separator">grouping-separator</termref>, 
        <termref def="id-static-decimal-format-percent">percent</termref>, 
        <termref def="id-static-decimal-format-per-mille">per-mille</termref>, 
        the family of ten decimal digits starting with <termref def="id-static-decimal-format-zero-digit">zero-digit</termref>, 
        <termref def="id-static-decimal-format-digit">digit</termref>, 
        and <termref def="id-static-decimal-format-pattern-separator">pattern-separator</termref>.</p>
               </item>
            </ulist>
            <example>
               <p>The following query formats numbers using two different decimal format declarations:</p>
               <eg role="parse-test" xml:space="preserve">
declare decimal-format local:de decimal-separator = "," grouping-separator = "."; 
declare decimal-format local:en decimal-separator = "." grouping-separator = ","; 
       
let $numbers := (1234.567, 789, 1234567.765) 
for $i in $numbers
return ( 
  format-number($i, "#.###,##", "local:de"), 
  format-number($i, "#,###.##", "local:en") 
)</eg>
               <p>The output of this query is:</p>
               <eg xml:space="preserve">1.234,57 1,234.57 789 789 1.234.567,76 1,234,567.76</eg>
            </example>
         </div2>
         <div2 id="id-schema-import">
            <head>Schema Import</head>
            <changes>
               <change issue="647" PR="659" date="2023-10-24">In previous versions the interpretation of location hints in 
        <code nobreak="false">import schema</code> declarations was entirely at the discretion of the processor. To
        improve interoperability, XQuery 4.0 recommends (but does not mandate)
        a specific strategy for interpreting these hints.</change>
               <change issue="451" PR="635">The rules for the consistency of schemas imported by different query modules,
        and for consistency between imported schemas and those used for validating input documents, have
        been defined with greater precision. It is now recognized that these schemas will not always be
        identical, and that validation with respect to different schemas may produce different outcomes,
        even if the components of one are a subset of the components of the other.</change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-SchemaImport">
                  <lhs>SchemaImport</lhs>
                  <rhs>"import"  "schema"  <nt def="prod-xquery40-SchemaPrefix">SchemaPrefix<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>  ("at"  (<nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt> ++ ","))?</rhs>
               </prod>

               <prod id="doc-xquery40-SchemaImport-SchemaPrefix">
                  <lhs>SchemaPrefix</lhs>
                  <rhs>("namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "=")  |  ("fixed"?  "default"  "element"  "namespace")</rhs>
               </prod>

               <prod id="doc-xquery40-SchemaImport-URILiteral">
                  <lhs>URILiteral</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-SchemaImport-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-schema-import" term="schema import">A <term>schema import</term> imports the
        element declarations, attribute declarations, and type definitions from a schema into the
          <termref def="dt-issd">in-scope schema definitions</termref>. For each named user-defined
        simple type in the schema, schema import also adds a corresponding <termref def="dt-constructor-function">constructor function</termref>. </termdef> The schema to be
      imported is identified by its <termref def="dt-target-namespace">target namespace</termref>.
      The schema import may bind a namespace prefix to the target namespace of the imported schema,
      adding the (prefix, URI) pair to the <termref def="dt-static-namespaces">statically known
        namespaces</termref>, or it may declare that target namespace to be the <termref def="dt-default-namespace-elements-and-types"/>. The schema import may
      also provide optional hints for locating the schema.</p>
            <p>The namespace prefix specified in a schema import must not be <code nobreak="false">xml</code> or
        <code nobreak="false">xmlns</code>
               <errorref class="ST" code="0070"/>, and must not be the same as any namespace prefix bound in
      the same module by another schema import, a <termref def="dt-module-import">module
        import</termref>, a <termref def="dt-namespace-declaration">namespace declaration</termref>,
      or a <termref def="dt-module-import">module declaration</termref>
               <errorref class="ST" code="0033"/>. </p>
            <note diff="add" at="issue647">
               <p>If schema definitions from the <code nobreak="false">xml</code> namespace
    are to be used (for example, <code nobreak="false">schema-attribute(xml:space)</code>, then the prolog should
      include a declaration in the form <code nobreak="false">import schema "http://www.w3.org/XML/1998/namespace"</code>.
    No prefix should be supplied (the <code nobreak="false">xml</code> prefix is predeclared), and no location hint
    should be provided (the schema definitions for the namespace are built in, and cannot be varied).</p>
            </note>
            <p diff="add" at="A">If the schema import declaration specifies <code nobreak="false">default element namespace</code>
      then the prolog must not contain a <termref def="dt-namespace-declaration">namespace declaration</termref>
      that specifies <code nobreak="false">default element namespace</code> or <code nobreak="false">default type namespace</code>.</p>
            <p diff="add" at="2023-10-16">If the keyword <code nobreak="false">"fixed"</code>, is present, the 
      <termref def="dt-default-namespace-elements-and-types"/> is fixed throughout the module,
      and is not affected by default namespace declarations (<code nobreak="false">xmlns=""</code>) appearing
      on direct element constructors.</p>
            <p> The first <nt def="prod-xquery40-URILiteral">URILiteral<!--$spec = xquery40--></nt> in a schema import specifies the target
      namespace of the schema to be imported.
    </p>
            <p>
      If the target
      namespace is <code nobreak="false">http://www.w3.org/2005/xpath-functions</code> then the schema described in 
      <xspecref spec="FO40" ref="schemata"/> is imported; any location hints are ignored.
    </p>
            <p>A schema import that specifies a zero-length string as target namespace is considered to
      import a schema that has no target namespace. Such a schema import must not bind a namespace
      prefix <errorref class="ST" code="0057"/>, but it may set the default element and/or type namespace
      to a zero-length string (representing “no namespace”), thus enabling the definitions in the
      imported namespace to be referenced. If the <termref def="dt-default-namespace-elements-and-types"/> is not set to "no
      namespace", <phrase diff="chg" at="A">the only way to reference the definitions in an imported schema that has no
        target namespace is using the EQName syntax <code nobreak="false">Q{}local-name</code>
               </phrase>.</p>
            <p diff="chg" at="issue647">The <nt def="prod-xquery40-URILiteral">URILiterals<!--$spec = xquery40--></nt> 
      that follow the <code nobreak="false">at</code> keyword are 
      optional location hints, intended to allow a processor to locate schema documents containing 
      definitions of the required schema components in the target namespace. Processors <rfc2119>may</rfc2119> 
      interpret or disregard these hints in an <termref def="dt-implementation-defined">implementation-defined</termref> way. The preferred strategy,
      which <rfc2119>should</rfc2119> be used by default unless the user indicates otherwise, 
      is as follows:</p>
            <olist diff="add" at="issue647">
               <item>
                  <p>If the target namespace is one for which the processor has built-in knowledge,
      for example the schema for a <termref def="dt-reserved-namespaces">reserved namespace</termref>, the location hints
      <rfc2119>should</rfc2119> be ignored, and the built-in schema used in preference.</p>
               </item>
               <item>
                  <p>In other cases, the location hints are taken in order, treating them as URI references relative
        to the static base URI of the query module.</p>
               </item>
               <item>
                  <p>If the first location hint cannot be successfully dereferenced, then that location hint is disregarded 
        (optionally with a warning), and the process continues with the next location hint, until
        one is found that can be successfully dereferenced; if none of the location hints can be dereferenced, 
        then a static error is reported.</p>
               </item>
               <item>
                  <p>The dereferencing of a location hint <rfc2119>may</rfc2119> make use of <termref def="dt-implementation-defined">implementation-defined</termref>
        indirection mechanisms such as resolver callbacks and catalog files.</p>
               </item>
               <item>
                  <p>If a location hint is successfully dereferenced, but yields a resource that cannot be parsed as a valid
        XSD schema document with the correct target namespace, then a static error is reported.</p>
               </item>
               <item>
                  <p>If a valid schema document is located, then it is combined with the schema documents obtained
        from other import schema declarations, in the same way as a schema is assembled from multiple
        schema documents referenced using <code nobreak="false">xs:import</code> declarations. This implies that the 
        several schema documents must together comprise a valid schema, for example there cannot be two 
        different type definitions with the same name.</p>
               </item>
               <item>
                  <p>Once one location hint has been successfully processed, subsequent location hints are
      ignored.</p>
               </item>
            </olist>
            <note diff="add" at="issue647">
               <p>Processors that adopted a different strategy in earlier releases <rfc2119>may</rfc2119>
      continue to use that strategy by default, in order to retain compatibility; however such
      processors <rfc2119>should</rfc2119> offer the above strategy as an option. </p>
               <p>The process described above is not intended to be totally prescriptive, or to guarantee complete 
      interoperability. Processors are likely to exhibit variations, depending both on design decisions made
      by the product vendor, and on decisions made when configuring the platform
      and network infrastructure on which it runs. For example, when retrieving HTTP resources,
      the details of the HTTP request are likely to vary, and the criteria used to decide whether
      a request was successful may also vary. In addition, the XSD specification itself describes
      some aspects of the process incompletely, including for example the criteria used to decide 
      whether two components (such as type definitions) should be considered identical.</p>
            </note>
            <p>Different query modules may import different schemas, but there is a requirement that all the schemas
      used by a query <rfc2119>must</rfc2119> be compatible. The rules for compatibility are defined
      in <xspecref spec="DM40" ref="schema-consistency"/>. This means, for example:</p>
            <ulist>
               <item>
                  <p>If any schema component (such as an element declaration or complex type definition)
      is imported into more than one query module, the definitions of these components must effectively 
      be the same.</p>
               </item>
               <item>
                  <p>This leaves room, however, for some differences between modules. For example, 
      the substitution group membership of an element declaration may vary between one module
      and another, depending on what other element declarations are present in the schema. This
      means that an element can be validated in one module and passed as a function parameter
      to another module in which the element would be considered invalid. Any static type inferencing
      that is performed must take such possibilities into account; this is particularly important
      if query modules are compiled independently from one another.</p>
               </item>
            </ulist>
            <p>
      If the target
      namespace is <code nobreak="false">http://www.w3.org/2005/xpath-functions</code> then the schema described in 
      <xspecref spec="FO31" ref="schemata"/> is imported; any location hints are ignored.
    </p>
            <p>It is a <termref def="dt-static-error">static error</termref>
               <errorref class="ST" code="0058"/> if more than one schema import in the same <termref def="dt-prolog">Prolog</termref> specifies the same target namespace. It is a <termref def="dt-static-error">static error</termref>
               <errorref class="ST" code="0059"/> if the implementation is not able to process a schema
      import by finding a valid schema with the specified target namespace. 
      <phrase diff="del" at="issue647">It is a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0035"/> if multiple imported schemas, or multiple physical
      resources within one schema, contain definitions for the same name in the same symbol space
      (for example, two definitions for the same element name, even if the definitions are
      consistent). However, it is not an error to import the schema with target namespace
        <code nobreak="false">http://www.w3.org/2001/XMLSchema </code>(predeclared prefix <code nobreak="false">xs</code>), even
      though the built-in types defined in this schema are implicitly included in the <termref def="dt-is-types">in-scope schema types.</termref>
               </phrase>
            </p>
            <p> It is a <termref def="dt-static-error">static error</termref>
               <errorref code="0012" class="ST"/> if the set of definitions contained in all schemas imported
      by a Prolog do not satisfy the conditions for schema validity specified in Sections 3 and 5 of
        <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/> Part 1: in particular, each definition
      must be valid, complete, and unique.</p>
            <p> It is a <termref def="dt-static-error">static error</termref>
               <errorref code="0149" class="ST"/> if the schemas imported by different modules of a query
      are not compatible as defined in <xspecref spec="DM40" ref="schema-consistency"/>.</p>
            <p>The following example imports a schema, specifying both its target namespace and its
      location, and binding the prefix <code nobreak="false">soap</code> to the target namespace:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">import schema namespace soap="http://www.w3.org/2003/05/soap-envelope" 
  at "http://www.w3.org/2003/05/soap-envelope/";</eg>
            <p>The following example imports a schema by specifying only its target namespace, and makes it
      the <termref def="dt-default-namespace-elements-and-types"/>:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">import schema default element namespace "http://example.org/abc";</eg>
            <p>The following example imports a schema that has no target namespace, providing a location
      hint, and sets the <termref def="dt-default-namespace-elements-and-types"/> to “no namespace” so that the definitions in
      the imported schema can be referenced:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">import schema default element namespace "" at "http://example.org/xyz.xsd";</eg>
            <p>The following example imports a schema that has no target namespace and sets the 
      <termref def="dt-default-namespace-elements-and-types"/> to “no namespace”. 
      Since no location hint is provided, it is up to the
      implementation to find the schema to be imported.</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">import schema default element namespace "";</eg>
            <p>Access to schema documents as external resources is possible only when either
      (a) the query is <termref def="dt-trusted"/>, or (b) the external resource in question
    has been explicitly made available by a <termref def="dt-trusted"/> caller.</p>
         </div2>
         <div2 id="id-module-import">
            <head>Module Import</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ModuleImport">
                  <lhs>ModuleImport</lhs>
                  <rhs>"import"  "module"  ("namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "=")?  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>  ("at"  (<nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt> ++ ","))?</rhs>
               </prod>

               <prod id="doc-xquery40-ModuleImport-URILiteral">
                  <lhs>URILiteral</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ModuleImport-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <termdef term="module import" id="dt-module-import">A <term>module import</term> imports the
        public variable declarations, public function declarations<phrase diff="add" at="A">, 
          and public item type declarations</phrase> from one or more <termref def="dt-library-module">library modules</termref> into the <termref def="dt-statically-known-function-definitions"/>, <termref def="dt-in-scope-variables">in-scope variables</termref>
                  <phrase diff="add" at="A">,
          or <termref def="dt-in-scope-named-item-types"/>
                  </phrase> of the importing <termref def="dt-module">module</termref>.</termdef> Each module import names a <termref def="dt-target-namespace">target namespace</termref> and imports an <termref def="dt-implementation-defined">implementation-defined</termref> set of modules that share
      this target namespace. The module import may bind a namespace prefix to the target namespace,
      adding the (prefix, URI) pair to the <termref def="dt-static-namespaces">statically known
        namespaces</termref>, and it may provide optional hints for locating the modules to be
      imported.</p>
            <p>If a module <var>A</var> imports module <var>B</var>, the static context of module
      <var>A</var> will contain the <termref def="dt-statically-known-function-definitions"/>, <termref def="dt-in-scope-variables">in-scope variables</termref>
               <phrase diff="add" at="A">,
            or <termref def="dt-in-scope-named-item-types"/>
               </phrase> of
      module <var>B</var>, and the dynamic context of module <var>A</var> will contain the
        public <termref def="dt-variable-values">variable values</termref> and <termref def="dt-dynamically-known-function-definitions"/> of module <var>B</var>. It will
      not contain:</p>
            <ulist>
               <item>
                  <p>Private functions, variables, and item types declared in <var>B</var>.</p>
               </item>
               <item>
                  <p>Functions, variables, and item types not
      declared directly in <var>B</var>, but imported from some other library module.</p>
               </item>
               <item>
                  <p>Other components such as <termref def="dt-issd">in-scope schema definitions</termref> or <termref def="dt-static-namespaces">statically known namespaces</termref> declared in <var>B</var>.</p>
               </item>
            </ulist>
            <p>The following example illustrates a module import:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">import module namespace gis="http://example.org/gis-functions";</eg>
            <p>If a query imports the same module via multiple paths, only one instance of the module is
      imported. Because only one instance of a module is imported, there is only one instance of
      each variable declared in a module's prolog.</p>
            <p>A module may import its own target namespace (this is interpreted as importing an <termref def="dt-implementation-defined">implementation-defined</termref> set of other modules that
      share its target namespace.)</p>
            <p>The namespace prefix specified in a module import must not be <code nobreak="false">xml</code> or
        <code nobreak="false">xmlns</code>
               <errorref class="ST" code="0070"/>, and must not be the same as any namespace prefix bound in
      the same module by another module import, a <termref def="dt-schema-import">schema
        import</termref>, a <termref def="dt-namespace-declaration">namespace declaration</termref>,
      or a <termref def="dt-module-declaration">module declaration</termref> with a different target
      namespace <errorref class="ST" code="0033"/>.</p>
            <p>The first <nt def="prod-xquery40-URILiteral">URILiteral<!--$spec = xquery40--></nt> in a module import must be of nonzero length
        <errorref class="ST" code="0088"/>, and specifies the target namespace of the modules to be
      imported. The <nt def="prod-xquery40-URILiteral">URILiterals<!--$spec = xquery40--></nt> that follow the <code nobreak="false">at</code> keyword are 
      optional location hints, and can be interpreted or disregarded in
      an <termref def="dt-implementation-defined">implementation-defined</termref> way.</p>
            <p>It is a <termref def="dt-static-error">static error</termref>
               <errorref class="ST" code="0047"/> if more than one module import in a <termref def="dt-prolog">Prolog</termref> specifies the same target namespace. It is a <termref def="dt-static-error">static error</termref>
               <errorref class="ST" code="0059"/> if the implementation is not able to process a module
      import by finding a valid module definition with the specified target namespace. It is a
        <termref def="dt-static-error">static error</termref> if two or more variables declared or
      imported by a <termref def="dt-module">module</termref> have equal <termref def="dt-expanded-qname">expanded QNames</termref> (as defined by the <code nobreak="false">eq</code>
      operator) <errorref class="ST" code="0049"/>.</p>
            <p>Module imports are not transitive. Importing a module provides access only to 
      declarations contained directly in the imported module. For example, if 
      module <var>A</var> imports
      module <var>B</var>, and module <var>B</var> imports module <var>C</var>, 
      module <var>A</var> does not have access to the functions and
      variables declared in module <var>C</var>. </p>
            <p>Access to library modules as external resources is possible only when either
      (a) the query is <termref def="dt-trusted"/>, or (b) the external resource in question
    has been explicitly made available by a <termref def="dt-trusted"/> caller.</p>
            <example>
               <head>Schema Information and Module Import</head>
               <p>A module import does not import schema definitions from the imported module. In the
        following query, the type <code nobreak="false">geometry:triangle</code> is not defined, even if it is known in the
        imported module, so the variable declaration raises an error <errorref class="ST" code="0051"/>:</p>
               <eg role="parse-test" xml:space="preserve">(: Error - geometry:triangle is not defined :) 
import module namespace geo = "http://example.org/geo-functions"; 
declare variable $triangle as geometry:triangle := geo:make-triangle(); 
$triangle</eg>
               <p>Without the type declaration for the variable, the variable declaration succeeds:</p>
               <eg role="parse-test" xml:space="preserve">import module namespace geo = "http://example.org/geo-functions";
declare variable $triangle := geo:make-triangle();
$triangle</eg>
               <p>Importing the schema that defines the type of the variable,
      the variable declaration succeeds:</p>
               <eg role="parse-test" xml:space="preserve">import schema namespace geometry = "http://example.org/geo-schema-declarations"; 
import module namespace geo = "http://example.org/geo-functions"; 
declare variable $triangle as geometry:triangle := geo:make-triangle();
$triangle</eg>
            </example>
            <div3 id="id-module-handling-module-uris">
               <head>The Target Namespace of a Module</head>
               <p>The target namespace of a module should be treated in the same way as other namespace
        URIs.</p>
               <p>To maximize interoperability, query authors should use a string that is a valid absolute
        IRI.</p>
               <p>Implementions must accept any string of Unicode characters. Target namespace URIs are
        compared using the Unicode codepoint collation rather than any concept of semantic
        equivalence.</p>
               <p>Implementations may provide mechanisms allowing the target namespace URI to be used as
        input to a process that delivers the module as a resource, for example a catalog, module
        repository, or URI resolver. For interoperability, such mechanisms should not prevent the
        user from choosing an arbitrary URI for naming a module.</p>
               <p>Similarly, implementations may perform syntactic transformations on the target namespace
        URI to obtain the names of related resources, for example to implement a convention relating
        the name or location of compiled code to the target namespace URI; but again, such
        mechanisms should not prevent the user from choosing an arbitrary target namespace URI.</p>
               <p>As with other namespace URIs, it is common practice to use target namespace URIs whose
        scheme is <code nobreak="false">http</code> and whose authority part uses a DNS domain name under the control of the
        user.</p>
               <p>The specifications allow, and some users might consider it good practice, for the target
        namespace URI of a function library to be the same as the namespace URI of the XML
        vocabulary manipulated by the functions in that library.</p>
            </div3>
            <div3 id="id-module-handling-multiple-same">
               <head>Multiple Modules with the same Namespace</head>
               <p>Several different modules with the same target namespace can be used in the same query. The
        names of public variables and public functions must be unique within the <termref def="dt-static-context"/> of a query: this means that if two modules with
        the same target namespace URI are used in the same query, the names of the public variables
        and functions in their module contexts must not overlap.</p>
               <p>If one module contains an <code nobreak="false">import module</code> declaration with the target namespace
          <code nobreak="false">M</code>, then all public variables and public functions in the contexts of modules
        whose target namespace is <code nobreak="false">M</code> must be accessible in the importing module,
        regardless whether the participation of the imported module was directly due to this "import
        module" declaration.</p>
            </div3>
            <div3 id="id-module-handling-location-uris">
               <head>Location URIs</head>
               <p>The term “location URIs” refers to the URIs in the <code nobreak="false">at</code> clause of an
        <code nobreak="false">import module</code> declaration.</p>
               <p>Products should (by default or at user option) take account of all the location URIs in an
        <code nobreak="false">import module</code> declaration, treating each location URI as a reference to a module with the
        specified target namespace URI. Location URIs should be made absolute with respect to the
        static base URI of the module containing the <code nobreak="false">import module</code> declaration where they appear.
        The mapping from location URIs to module source code or compiled code MAY be done in any way
        convenient to the implementation. If possible given the product’s architecture, security
        requirements, etc, the product should allow this to fetch the source code of the module to
        use the standard web mechanisms for dereferencing URIs in standard schemes such as the
        <code nobreak="false">http</code> URI scheme.</p>
               <p>When the same absolutized location URI is used more than once, either in the same
        <code nobreak="false">import module</code> declaration or in different
        <code nobreak="false">import module</code> declarations within the same query, a
        single copy of the resource containing the module is loaded. When different absolutized
        location URIs are used, each results in a single module being loaded, unless the
        implementation is able to determine that the different URIs are references to the same
        resource. No error due to duplicate variable or functions names should arise from the same
        module being imported more than once, so long as the absolute location URI is the same in
        each case.</p>
               <p>Implementations must report a static error if a location URI cannot be resolved after all
        available recovery strategies have been exhausted.</p>
            </div3>
            <div3 id="id-module-handling-cycles">
               <head>Cycles</head>
               <p>Implementations must resolve cycles in the import graph, either at the level of target
        namespace URIs or at the level of location URIs, and ensure that each module is imported
        only once. </p>
            </div3>
         </div2>
         <div2 id="id-namespace-declaration">
            <head>Namespace Declaration</head>
            <changes>
               <change>
        All implementations must now predeclare the namespace prefixes
        <code nobreak="false">math</code>, <code nobreak="false">map</code>, <code nobreak="false">array</code>, and <code nobreak="false">err</code>. In XQuery 3.1 it was permitted
        but not required to predeclare these namespaces.
      </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-NamespaceDecl">
                  <lhs>NamespaceDecl</lhs>
                  <rhs>"declare"  "namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NamespaceDecl-URILiteral">
                  <lhs>URILiteral</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NamespaceDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-namespace-declaration" term="namespace declaration">A <term>namespace
          declaration</term> declares a namespace prefix and associates it with a namespace URI,
        adding the (prefix, URI) pair to the set of <termref def="dt-static-namespaces">statically
          known namespaces</termref>.</termdef> The namespace declaration is in scope throughout the
      query in which it is declared, unless it is overridden by a <termref def="dt-namespace-decl-attr">namespace declaration attribute</termref> in a <termref def="dt-direct-elem-const">direct element constructor</termref>.</p>
            <p>If the URILiteral part of a namespace declaration is a zero-length string, any existing
      namespace binding for the given prefix is removed from the <termref def="dt-static-namespaces">statically known namespaces</termref>. This feature provides a way to remove predeclared
      namespace prefixes such as <code nobreak="false">local</code>.</p>
            <p>The following query illustrates a namespace declaration:</p>
            <eg role="parse-test" xml:space="preserve">
declare namespace foo = "http://example.org";
&lt;foo:bar&gt; Lentils &lt;/foo:bar&gt;
    </eg>
            <p>In the query result, the newly created node is in the namespace associated with the namespace
      URI <code nobreak="false">http://example.org</code>.</p>
            <p>The namespace prefix specified in a namespace declaration must not be <code nobreak="false">xml</code> or
        <code nobreak="false">xmlns</code>
               <errorref class="ST" code="0070"/>. The namespace URI specified in a namespace declaration
      must not be <code nobreak="false">http://www.w3.org/XML/1998/namespace</code> or
        <code nobreak="false">http://www.w3.org/2000/xmlns/</code>
               <errorref class="ST" code="0070"/>. The namespace prefix specified in a namespace declaration
      must not be the same as any namespace prefix bound in the same module by a <termref def="dt-module-import">module import</termref>, <termref def="dt-schema-import">schema
        import</termref>, <termref def="dt-module-import">module declaration</termref>, or another
      namespace declaration <errorref class="ST" code="0033"/>. </p>
            <p>It is a <termref def="dt-static-error">static error</termref>
               <errorref class="ST" code="0081"/> if an expression contains a <termref def="dt-qname">lexical
        QName</termref> with a namespace prefix that is not in the <termref def="dt-static-namespaces">statically known namespaces</termref>.</p>
            <p>XQuery has several predeclared namespace prefixes, which are listed in
      <specref ref="id-namespaces-and-qnames"/>.
        These prefixes may be used without an explicit declaration; they are present in the
        <termref def="dt-static-namespaces">statically known namespaces</termref>
        before each query is processed. They may be overridden by
        <termref def="dt-namespace-declaration">namespace declarations</termref> in a <termref def="dt-prolog">Prolog</termref> or by <termref def="dt-namespace-decl-attr">namespace
        declaration attributes</termref> on constructed elements (however, the prefix
        <code nobreak="false">xml</code> must not be redeclared, and no other prefix may be bound to the namespace
      URI associated with the prefix <code nobreak="false">xml</code>
               <errorref class="ST" code="0070"/>).
    </p>
            <p>Additional predeclared namespace prefixes may be added to the <termref def="dt-static-namespaces">statically known namespaces</termref> by an implementation.</p>
            <p>When element or attribute names are compared, they are considered identical if the local
      parts and namespace URIs match on a codepoint basis. Namespace prefixes need not be identical
      for two names to match, as illustrated by the following example:</p>
            <eg role="parse-test" xml:space="preserve">
declare namespace xx = "http://example.org";

let $node := &lt;foo:bar xmlns:foo = "http://example.org"&gt;
  &lt;foo:bing&gt; Lentils &lt;/foo:bing&gt;
&lt;/foo:bar&gt;
return $node/xx:bing
    </eg>
            <p>Although the namespace prefixes <code nobreak="false">xx</code> and <code nobreak="false">foo</code> differ, both are bound
      to the namespace URI <code nobreak="false">http://example.org</code>. Since <code nobreak="false">xx:bing</code> and
        <code nobreak="false">foo:bing</code> have the same local name and the same namespace URI, they match. The
      output of the above query is as follows.</p>
            <eg role="parse-test" xml:space="preserve">
&lt;foo:bing xmlns:foo="http://example.org"&gt; Lentils &lt;/foo:bing&gt;
    </eg>
         </div2>
         <div2 id="id-default-namespace">
            <head>Default Namespace Declaration</head>
            <changes>
               <change issue="65" PR="753" date="2023-10-31">
        The <termref def="dt-default-namespace-elements-and-types"/> can now be declared to be fixed
        for a query module, meaning it is unaffected by a namespace declaration appearing on a direct
        element constructor.
      </change>
               <change issue="296" PR="1181" date="2023-04-30">
        The <termref def="dt-default-namespace-elements-and-types"/> can be set to the value <code nobreak="false">##any</code>,
        allowing unprefixed names in axis steps to match elements with a given local name in any namespace.
      </change>
               <change issue="657 2235" PR="2200 2236" date="2025-10-07">
        The effect of not declaring a default function namespace has changed: user-defined functions can
        now be in no namespace, and a search for an unprefixed function name will be resolved first
        against functions in no namespace, and only then against functions in the standard function namespace.
      </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-DefaultNamespaceDecl">
                  <lhs>DefaultNamespaceDecl</lhs>
                  <rhs>"declare"  "fixed"?  "default"  ("element"  |  "function")  "namespace"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-DefaultNamespaceDecl-URILiteral">
                  <lhs>URILiteral</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-DefaultNamespaceDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>
               <term>Default namespace declarations</term> can be used in a <termref def="dt-prolog">Prolog</termref> to facilitate the use of unprefixed QNames.</p>
            <p>The namespace URI specified in a default namespace declaration must not be
        <code nobreak="false">http://www.w3.org/XML/1998/namespace</code> or
        <code nobreak="false">http://www.w3.org/2000/xmlns/</code>
               <errorref class="ST" code="0070"/>.</p>
            <p>There are two kinds of default namespace declarations, described in the following sections.</p>
            <div3 id="id-default-element-namespace-declaration">
               <head>Default Element Namespace Declaration</head>
               <p>A <term>default element namespace declaration</term> declares how unprefixed element and type
          names are to be interpreted. The relevant value 
          is recorded as the <termref def="dt-default-namespace-elements-and-types"/> in the
          <termref def="dt-static-context">static context</termref> for the query module. A <termref def="dt-prolog">Prolog</termref> may contain at most one default element namespace declaration
          <phrase diff="add" at="A">and it must not contain
          both a default element namespace declaration and an <code nobreak="false">import schema</code> declaration
            that specifies a default element namespace</phrase>
                  <errorref class="ST" code="0066"/>.</p>
               <p>The <code nobreak="false">URILiteral</code> may take one of the following forms:</p>
               <ulist>
                  <item>
                     <p>A namespace URI. This namespace will typically be used for unprefixed names appearing
            where an element or type name is expected.</p>
                  </item>
                  <item>
                     <p>The empty string <code nobreak="false">""</code>. In this case unprefixed names appearing where
              an element or type name is expected are treated as being in no namespace: the
              <termref def="dt-default-namespace-elements-and-types"/> is set to <xtermref spec="DM40" ref="dt-absent"/>.</p>
                  </item>
                  <item>
                     <p>The string <code nobreak="false">"##any"</code>. In this case an unprefixed name appearing
              as a <nt def="prod-xquery40-NameTest">NameTest<!--$spec = xquery40--></nt> in an axis step whose principal node kind is element
              is interpreted as a wildcard (the unprefixed name <code nobreak="false">N</code> is treated as equivalent
              to the wildcard <code nobreak="false">*:N</code>); an unprefixed name used appearing where an item type name
              is expected is interpreted as a local name in namespace <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>,
              while an unprefixed name appearing in any other context
              where an element or type name is expected is treated as being in no namespace.</p>
                     <note>
                        <p>To take an example, older versions of the internet index of RFCs (requests for comments)
              use the namespace URI <code nobreak="false">http://www.rfc-editor.org/rfc-index</code>, while newer
              versions use <code nobreak="false">https://www.rfc-editor.org/rfc-index</code> (note the change of URI scheme).
              XPath code that needs to work with either version can be simplified by setting the
              default namespace to <code nobreak="false">##any</code>: but be aware that this might lead to spurious matching
              of names in an unrelated namespace.</p>
                     </note>
                  </item>
               </ulist>
               <p>The following example illustrates the declaration of a
          default namespace for elements and types:</p>
               <eg role="frag-prolog-parse-test" xml:space="preserve">declare default element namespace "http://example.org/names";</eg>
               <p>If no default element namespace declaration is present, unprefixed element and type
          names are in no namespace (however, an implementation may define a different default as
          specified in <specref ref="id-xq-static-context-components"/>.)</p>
               <p diff="add" at="2023-10-16">If the keyword <code nobreak="false">"fixed"</code>, is present, the 
          <termref def="dt-default-namespace-elements-and-types"/> is fixed throughout the module,
          and is not affected by default namespace declarations (<code nobreak="false">xmlns=""</code>) appearing
          on direct element constructors.</p>
            </div3>
            <div3 id="id-default-function-namespace-declaration">
               <head>Default Function Namespace Declaration</head>
               <p>A <term>default function namespace declaration</term> declares a namespace URI that is
          associated with unprefixed function names in 
          <termref def="dt-static-function-call">static function calls</termref> and 
          <termref def="dt-named-function-ref">named function references</termref>. It also
          affects the interpretation of unprefixed <termref def="dt-qname">lexical QNames</termref>
          used in function declarations.</p>
               <p>The following example illustrates the declaration of a default function namespace:</p>
               <eg role="frag-prolog-parse-test" xml:space="preserve">declare default function namespace "http://www.w3.org/2005/xpath-functions/math";</eg>
               <p>A <termref def="dt-prolog">Prolog</termref> may contain at most one
          default function namespace declaration <errorref class="ST" code="0066"/>.</p>
               <p>There are three cases to consider.</p>
               <olist>
                  <item>
                     <p>If there is an explicit default function namespace declaration and the
          <code nobreak="false">StringLiteral</code> is a zero-length string, the
          default function namespace is <xtermref spec="DM40" ref="dt-absent"/>.</p>
                     <p>In this case:</p>
                     <olist>
                        <item>
                           <p>Any function declaration using an unprefixed <termref def="dt-qname"/> declares a function
              in no namespace.</p>
                        </item>
                        <item>
                           <p>Any <termref def="dt-static-function-call"/> or 
                <termref def="dt-named-function-ref"/> using an unprefixed
              <termref def="dt-qname"/> refers to a function in no namespace.</p>
                        </item>
                        <item>
                           <p>Any function whose name is in a namespace (including the standard
              function namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>)
              can be referenced only by using an explicit namespace prefix
              (for example, <code nobreak="false">fn:abs(3)</code>) or an EQName that identifies
                the namespace explicitly (for example, 
                <code nobreak="false">Q{http://www.w3.org/2005/xpath-functions}abs(3)</code>).</p>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>If there is an explicit default function namespace declaration and the
          <code nobreak="false">StringLiteral</code> is a non-zero-length string (call it <var>NS</var>), the
          default function namespace is set to <var>NS</var>.</p>
                     <p>In this case:</p>
                     <olist>
                        <item>
                           <p>Any function declaration using an unprefixed <termref def="dt-qname"/> declares a function
              in namespace <var>NS</var>.</p>
                        </item>
                        <item>
                           <p>Any <termref def="dt-static-function-call"/> or 
                <termref def="dt-named-function-ref"/> using an unprefixed
              <termref def="dt-qname"/> refers to a function in namespace <var>NS</var>.</p>
                        </item>
                        <item>
                           <p>Any function whose name is in a different namespace (including the standard
              function namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>)
              can be referenced only by using an explicit namespace prefix (for example <code nobreak="false">fn:abs($x)</code>), or using
              an EQName that explicitly identifies the namespace (for example
              <code nobreak="false">Q{http://www.w3.org/2005/xpath-functions}abs($x)</code>).</p>
                        </item>
                        <item>
                           <p>Any function whose name is in no namespace (for example,
                a constructor function for an atomic type declared in a no-namespace schema)
              can be called only by using a no-namespace EQName, for example
              <code nobreak="false">Q{}local-name($x)</code>.</p>
                        </item>
                     </olist>
                  </item>
                  <item>
                     <p>If there is no explicit default function namespace declaration, then:</p>
                     <olist>
                        <item>
                           <p>Any function declaration using an unprefixed <termref def="dt-qname"/> declares a function
              in no namespace.</p>
                           <note>
                              <p>This is allowed only for functions in the main module, and for private
              functions in a library module.</p>
                              <p>In previous XQuery versions this would have been an error, as the 
              default namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code> was
              (and remains) a <termref def="dt-reserved-namespaces">reserved namespace</termref>.</p>
                           </note>
                        </item>
                        <item>
                           <p>Any <termref def="dt-static-function-call"/> or 
                <termref def="dt-named-function-ref"/> using an unprefixed
              <termref def="dt-qname"/> is resolved by first searching the static context for a declaration
              of a no-namespace function having the right local name and arity range, and if that
              is unsuccessful, by searching for a function in the standard
              function namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>
                having the right local name and arity range.</p>
                           <p>A no-namespace function can be referenced without risk of ambiguity
                  by using a no-namespace EQName, for example <code nobreak="false">Q{}local-name($x)</code>.</p>
                           <p>A function in the standard function namespace 
                  <code nobreak="false">http://www.w3.org/2005/xpath-functions</code> can be referenced without
                  risk of ambiguity by using the pre-declared namespace prefix <code nobreak="false">fn</code>
              (for example <code nobreak="false">fn:abs($x)</code>), or by using
              an EQName that explicitly identifies the namespace (for example
              <code nobreak="false">Q{http://www.w3.org/2005/xpath-functions}abs($x)</code>).</p>
                        </item>
                     </olist>
                  </item>
               </olist>
               <p diff="add" at="2023-10-16">The keyword <code nobreak="false">"fixed"</code> has no effect when declaring
          a default function namespace, since there is no mechanism to change the default function
          namespace within a query module.</p>
            </div3>
         </div2>
         <div2 id="id-annotations">
            <head>Annotations</head>
            <scrap headstyle="show">
               <prod id="doc-xquery40-Annotation">
                  <lhs>Annotation</lhs>
                  <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
               </prod>

               <prod id="doc-xquery40-Annotation-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-Annotation-Constant">
                  <lhs>Constant</lhs>
                  <rhs>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("-"?  <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>)  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("true"  "("  ")")  |  ("false"  "("  ")")</rhs>
               </prod>
            </scrap>
            <p>XQuery uses annotations to declare properties associated with functions (inline or declared
      in the prolog), variables, and named types. For instance, a function may be declared <code nobreak="false">%public</code> or
        <code nobreak="false">%private</code>. The semantics associated with these properties are described in
        <specref ref="FunctionDeclns"/>.</p>
            <note>
               <p>For ease of exposition, the EBNF grammar includes several productions that all start
      with <code nobreak="false">"declare" Annotation*</code>, followed by the type of declaration (one of
      <code nobreak="false">"variable"</code>, <code nobreak="false">"function"</code>, <code nobreak="false">"type"</code>, <code nobreak="false">"record"</code>).
      A parser generated automatically from the grammar in this form would require unbounded
      lookahead. For implementation purposes, the grammar can be refactored as
      <code nobreak="false">"declare" Annotation* ( "variable"... | "function"... | "type"... | "record"... )</code>.</p>
            </note>
            <p>Annotations are <code nobreak="false">(QName, value)</code> pairs. If the EQName of the annotation is a
        <termref def="dt-qname">lexical QName</termref> then it is expanded using the 
      <termref def="dt-default-annotation-namespace-rule"/>.</p>
            <note>
               <p>The default namespace is a <termref def="dt-reserved-namespaces">reserved namespace</termref>, which means
    that unprefixed names cannot be used for implementation-defined or user-defined
    annotations. It is permitted to use a no-namespace name, which
    might be written, for example, as <code nobreak="false">%Q{}inline</code>; however, this
    is discouraged because it is likely to reduce portability across implementations.</p>
            </note>
            <p>In general there is no rule preventing two annotations on the same declaration having
    the same name, although this is disallowed for some specific annotations such as
    <code nobreak="false">%public</code> and <code nobreak="false">%private</code>. The order of annotations may be significant.</p>
            <p>If there is no value associated with an annotation, the effective value is the empty sequence.
    This is the case, for example, with the annotations <code nobreak="false">%public</code> and <code nobreak="false">%private</code>.</p>
            <p role="xquery"> A few annotations, such as <code nobreak="false">%public</code> and <code nobreak="false">%private</code>,
      have rules defined by this specification. Implementations may define further annotations, whose behavior is
        implementation-defined. For instance, if the <code nobreak="false">eg</code> prefix is bound to a namespace
        recognized by a particular implementation, then it could be used to define an annotation like
          <code nobreak="false">eg:sequential</code>. 
        If the namespace URI of an annotation is not recognized by the 
        implementation, then the annotation has no effect, other than being available for inspection
        using the <function>fn:function-annotations</function> function.</p>
            <p>Implementations may also provide 
      a way for users to define their own annotations.
        Implementations must not define annotations, or allow users to define annotations, in 
         <termref def="dt-reserved-namespaces">reserved namespaces</termref>; it 
        is a <termref def="dt-static-error">static error</termref>
               <errorref class="ST" code="0045"/> 
        for the name of an annotation to be in a <termref def="dt-reserved-namespaces">reserved namespace</termref>.
     </p>
            <p diff="chg" at="issue637"> An annotation can provide values explicitly using a parenthesized list of 
      constant values. Constants are described in <specref ref="id-constants"/>.</p>
            <p>For example, the annotation
        <code nobreak="false">%java:method("java.lang.Math.sin")</code> sets the value of the
        <code nobreak="false">java:method</code> annotation to the string value <code nobreak="false">java.lang.Math.sin</code>. An implementation
      might define such annotations to facilitate calling external functions.
    </p>
         </div2>
         <div2 id="id-variable-declarations">
            <head>Variable Declaration</head>
            <changes>
               <change issue="189" PR="254" date="2022-11-29">
        The coercion rules are now used when binding values to variables (both
        global variable declarations and local variable bindings). This aligns XQuery with XSLT,
        and means that the rules for binding to variables are the same as the rules for binding
        to function parameters.
      </change>
               <change issue="1379" PR="1432" date="2024-09-12">
         In earlier versions, the static context for the <termref def="dt-initializing-expression"/>
         excluded the variable being declared. This restriction has been lifted.
      </change>
               <change issue="1954" PR="1956" date="2025-04-24">
        Private variables declared in a library module are no longer required to be in the module namespace.
      </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-VarDecl">
                  <lhs>VarDecl</lhs>
                  <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "variable"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  ((":="  <nt def="prod-xquery40-VarValue">VarValue<!--$idref_lang_part = xquery40- --></nt>)  |  ("external"  (":="  <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$idref_lang_part = xquery40- --></nt>)?))</rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-Annotation">
                  <lhs>Annotation</lhs>
                  <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-VarNameAndType">
                  <lhs>VarNameAndType</lhs>
                  <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-TypeDeclaration">
                  <lhs>TypeDeclaration</lhs>
                  <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-SequenceType">
                  <lhs>SequenceType</lhs>
                  <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-VarValue">
                  <lhs>VarValue</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-ExprSingle">
                  <lhs>ExprSingle</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-VarDecl-VarDefaultValue">
                  <lhs>VarDefaultValue</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p>
               <termdef id="dt-variable-declaration" term="variable declaration">A <term>variable declaration</term> 
      in the XQuery prolog defines the name and <termref def="dt-static-type">static
        type</termref> of a variable, and optionally a value for the variable. It adds to the 
        <termref def="dt-in-scope-variables">in-scope
        variables</termref> in the <termref def="dt-static-context"/>, and may also add to the <termref def="dt-variable-values">variable values</termref> in the <termref def="dt-dynamic-context"/>.</termdef>
            </p>
            <note>
               <p>The term <term>variable declaration</term> always refers to a declaration of a variable in a
        Prolog. The binding of a variable to a value in a query expression, such as a FLWOR
        expression, is known as a <term>variable binding</term>, and does not make the variable
        visible to an importing module.</p>
            </note>
            <p>The variable name, if written as a <termref def="dt-qname"/>, is expanded
      using the <termref def="dt-no-namespace-rule"/>.</p>
            <p>During static analysis, a variable declaration causes a pair <code nobreak="false">(expanded QName N, type
        T)</code> to be added to the <termref def="dt-in-scope-variables">in-scope
        variables</termref>. The <termref def="dt-expanded-qname"/> N is the <code nobreak="false">VarName</code>. If N is equal (as
      defined by the eq operator) to the expanded QName of another variable in in-scope variables, a
        <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0049"/>.
        
      The type T of the declared variable is as follows:
    </p>
            <ulist>
               <item>
                  <p>If <code nobreak="false">TypeDeclaration</code> is present, then the <code nobreak="false">SequenceType</code> in the
          <code nobreak="false">TypeDeclaration</code>; otherwise</p>
               </item>
               <!--<item>
        <p>If the Static Typing Feature is in effect and <code>VarValue</code> is present, then the
           static type inferred from static analysis of the expression <code>VarValue</code>;</p>

        <note>
          <p>Type inference might not be computable until after the check for circular dependencies,
             described below, is complete.</p>
        </note>
      </item>-->
               <item>
                  <p> Otherwise, <code nobreak="false">item()*</code>.</p>
               </item>
            </ulist>
            <p>A variable declaration may
      use annotations to specify that the variable is <code nobreak="false">%private</code> or <code nobreak="false">%public</code>
      (which is the default). <termdef id="dt-private-variable" term="private   variable">A
          <term>private variable</term> is a variable with a <code nobreak="false">%private</code> annotation. A
        private variable is hidden from <termref def="dt-module-import">module import</termref>,
        which can not import it into the <termref def="dt-in-scope-variables">in-scope
          variables</termref> of another module.</termdef>
               <termdef id="dt-public-variable" term="public variable">A <term>public variable</term> is a
        variable without a <code nobreak="false">%private</code> annotation. A public variable is accessible to
          <termref def="dt-module-import">module import</termref>, which can import it into the
          <termref def="dt-in-scope-variables">in-scope variables</termref> of another module. Using
          <code nobreak="false">%public</code> and <code nobreak="false">%private</code> annotations in a main module is not an
        error, but it does not affect module imports, since a main module cannot be imported. It is
        a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0116"/> if a variable declaration contains both a
          <code nobreak="false">%private</code> and a <code nobreak="false">%public</code> annotation, more than one
          <code nobreak="false">%private</code> annotation, or more than one <code nobreak="false">%public</code>
        annotation.</termdef>
            </p>
            <p>All <termref def="dt-public-variable"/> names declared in a library module must (when expanded) be in the target
      namespace of the library module <errorref class="ST" code="0048"/>.</p>
            <p>Here are some examples of variable declarations:</p>
            <ulist>
               <item>
                  <p>The following declaration specifies both the type and the value of a variable. This
          declaration causes the type <code nobreak="false">xs:integer</code> to be associated with variable
            <code nobreak="false">$x</code> in the <termref def="dt-static-context">static context</termref>, and
          the value <code nobreak="false">7</code> to be associated with variable <code nobreak="false">$x</code> in the <termref def="dt-dynamic-context">dynamic context</termref>.</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $x as xs:integer := 7;</eg>
               </item>
               <item>
                  <p>The following declaration specifies a value but not a type. The <termref def="dt-static-type">static type</termref> of the variable is inferred from the static
          type of its value. In this case, the variable <code nobreak="false">$x</code> has a static type of
            <code nobreak="false">xs:decimal</code>, inferred from its value which is 7.5.</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $x := 7.5;</eg>
               </item>
               <item>
                  <p>The following declaration specifies a type but not a value. The keyword
            <code nobreak="false">external</code> indicates that the value of the variable will be provided by the
          external environment. At evaluation time, if the variable <code nobreak="false">$x</code> in the <termref def="dt-dynamic-context">dynamic context</termref> does not have a value of type
            <code nobreak="false">xs:integer</code>, a <termref def="dt-type-error">type error</termref> is
          raised.</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $x as xs:integer external;</eg>
               </item>
               <item>
                  <p>The following declaration specifies neither a type nor a value. It simply declares that
          the query depends on the existence of a variable named <code nobreak="false">$x</code>, whose type and
          value will be provided by the external environment. During query analysis, the type of
            <code nobreak="false">$x</code> is considered to be <code nobreak="false">item()*</code>. During query evaluation, the
            <termref def="dt-dynamic-context">dynamic context</termref> must include a type and a
          value for <code nobreak="false">$x</code>, and its value must be compatible with its type.</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $x external;</eg>
               </item>
               <item>
                  <p>The following declaration, which might appear in a library module, declares a variable
          whose name includes a namespace prefix:</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $sasl:username as xs:string := "jonathan@example.com";</eg>
               </item>
               <item>
                  <p>This is an example of an external variable declaration that provides a
            <code nobreak="false">VarDefaultValue</code>:</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $x as xs:integer external := 47;</eg>
               </item>
            </ulist>
            <p>
      An implementation can provide annotations it needs. For instance,
      an implementation that supports volatile external variables
      might allow them to be declared using an annotation:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare %eg:volatile variable $time as xs:time external;</eg>
            <p>
               <termdef term="initializing expression" id="dt-initializing-expression">If a variable
        declaration includes an expression (<code nobreak="false">VarValue</code> or <code nobreak="false">VarDefaultValue</code>),
        the expression is called an <term>initializing expression.</term> The static context for an
        initializing expression includes all functions, variables, and namespaces that are declared
        or imported anywhere in the Prolog.</termdef>
            </p>
            <p diff="add" at="2022-11-17">If a required type is defined, then the value obtained by 
      evaluating the initializing expression is converted to the required type by applying
    the <termref def="dt-coercion-rules"/>. A type error occurs if this is not possible.
      In invoking the <termref def="dt-coercion-rules"/>, <termref def="dt-xpath-compat-mode"/> does not apply.</p>
            <p>In a module's dynamic context, a variable value (or the context value) may <termref def="dt-depends-on">depend on</termref> another variable value (or the context value).
        <termdef id="dt-depends-on" term="depends on">A variable value (or the context value)
          <term>depends on</term> another variable value (or the context value) if, during the
        evaluation of the initializing expression of the former, the latter is accessed through the
        module context.</termdef>
            </p>
            <p>In the following example, the value of variable <code nobreak="false">$a</code>
               <termref def="dt-depends-on">depends on</termref> the value of variable <code nobreak="false">$b</code>
      because the evaluation of $a's initializing expression accesses the value of $b during the
      evaluation of <code nobreak="false">local:f()</code>.</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $a := local:f(); 
declare variable $b := 1;
declare function local:f() { $b }; </eg>
            <p>A directed graph can be built with all variable values and the context value as nodes, and
      with the <termref def="dt-depends-on">depend on</termref> relation as edges. This graph must
      not contain cycles, as it makes the population of the dynamic context impossible. If it is
      discovered, during static analysis or during dynamic evaluation, that such a cycle exists,
      error <errorref class="DY" code="0054"/> must be raised.</p>
            <!-- ================================================= -->
            <p>During query evaluation, each variable declaration causes a pair <code nobreak="false">(expanded QName <var>N</var>,
        value <var>V</var>)</code> to be added to the <termref def="dt-variable-values">variable
        values</termref>. The <termref def="dt-expanded-qname"/>
               <var>N</var> is the expanded name of the variable. The value <var>V</var> is as
      follows:</p>
            <ulist>
               <item>
                  <p>If <code nobreak="false">VarValue</code> is specified, then <var>V</var> is the result of evaluating
            <code nobreak="false">VarValue</code>.</p>
               </item>
               <item>
                  <p> If <code nobreak="false">external</code> is specified, then:</p>
                  <ulist>
                     <item>
                        <p> if a value is provided for the variable by the external environment, then <var>V</var> is that
              value. The means by which typed values of external variables are provided by the
              external environment is implementation-defined.</p>
                     </item>
                     <item>
                        <p> if no value is provided for the variable by the external environment, and
                <code nobreak="false">VarDefaultValue</code> is specified, then <var>V</var> is the result of evaluating
                <code nobreak="false">VarDefaultValue</code>.</p>
                     </item>
                     <item>
                        <p>If no value is provided for the variable by the external environment, and
                <code nobreak="false">VarDefaultValue</code> is not specified, then a <termref def="dt-dynamic-error">dynamic error</termref> is raised <errorref class="DY" code="0002"/>. </p>
                        <p>It is implementation-dependent whether this error is raised if the evaluation of the
              query does not reference the value of the variable.</p>
                     </item>
                  </ulist>
               </item>
            </ulist>
            <p>In all cases the value <var>V</var> must match the type <var>T</var> according to the rules for SequenceType
      matching; otherwise a <termref def="dt-type-error">type error</termref> is raised <errorref class="TY" code="0004"/>.</p>
         </div2>
         <div2 id="id-context-value-declarations">
            <head>Context Value Declaration</head>
            <changes>
               <change issue="129" PR="368" date="2023-07-21">
        The concept of the context item has been generalized, so it is now a context value. That is,
        it is no longer constrained to be a single item.
      </change>
               <change issue="189 2040" PR="254 2050" date="2025-06-13">
        The supplied context value is now coerced to the required type specified in the main module
        using the coercion rules.
      </change>
            </changes>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ContextValueDecl">
                  <lhs>ContextValueDecl</lhs>
                  <rhs>"declare"  "context"  (("value"  ("as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?)  |  ("item"  ("as"  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>)?))  ((":="  <nt def="prod-xquery40-VarValue">VarValue<!--$idref_lang_part = xquery40- --></nt>)  |  ("external"  (":="  <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$idref_lang_part = xquery40- --></nt>)?))</rhs>
               </prod>

               <prod id="doc-xquery40-ContextValueDecl-SequenceType">
                  <lhs>SequenceType</lhs>
                  <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
               </prod>

               <prod id="doc-xquery40-ContextValueDecl-ItemType">
                  <lhs>ItemType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ContextValueDecl-VarValue">
                  <lhs>VarValue</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ContextValueDecl-ExprSingle">
                  <lhs>ExprSingle</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ContextValueDecl-VarDefaultValue">
                  <lhs>VarDefaultValue</lhs>
                  <rhs>
                     <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <!-- ================================================================== -->
            <p>A context value declaration allows a query to specify the <termref def="dt-static-type">static
        type</termref>, value, or default value for the <termref def="dt-initial-context-value">initial context value</termref>.</p>
            <p>Only the main module can set the <termref def="dt-initial-context-value">initial
        context value</termref>. In a library module, a context value declaration must be external,
      and specifies only the static type. Specifying a <nt def="prod-xquery40-VarValue">VarValue<!--$spec = xquery40--></nt> or <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$spec = xquery40--></nt> for a context value declaration in a library
      module is a static error <errorref class="ST" code="0113"/>.</p>
            <p>The form <code nobreak="false">declare context value</code> allows the <termref def="dt-initial-context-value"/>
    to be set to any value, with any sequence type. The alternative form <code nobreak="false">declare context item</code>
    is retained for compatibility with earlier versions of XQuery, and requires the value to be a single
    item, and the type (if specified) to be an item type.</p>
            <p>In every module that does not contain a context value declaration, the effect is as if the
      declaration</p>
            <eg xml:space="preserve">declare context value as item()* external;</eg>
            <p>appeared in that module.</p>
            <p>The context value declaration has the effect of defining a required type for the context value.
      When the form <code nobreak="false">declare context value</code> is used, the default type is <code nobreak="false">item()*</code>.
      When the alternative form <code nobreak="false">declare context item</code> is used, the default type is
      <code nobreak="false">item()</code>.</p>
            <p>If a module contains more than one context value declaration, a static error is raised
        <errorref class="ST" code="0099"/>.</p>
            <p>During query evaluation, a <termref def="dt-fixed-focus">fixed focus</termref> is
      created in the dynamic context for the evaluation of the <code nobreak="false">QueryBody</code> in the main
      module, and for the initializing expression of every variable declaration in every module.
      
      
      The context value of this fixed focus is called
      the <termref def="dt-initial-context-value">initial context value</termref>,
      which is selected as follows:
      
      </p>
            <ulist>
               <item>
                  <p>If <code nobreak="false">VarValue</code> is specified, then
          the initial context value is
          the result of evaluating <code nobreak="false">VarValue</code>, coerced to the required type
          as described below.</p>
                  <note>
                     <p>
            In such a case,
            the initial context value does not obtain its value from the external environment.
            If the external environment attempts to provide a value for the initial context value,
            it is outside the scope of this specification
            whether that is ignored, or results in an error.
          </p>
                  </note>
               </item>
               <item>
                  <p>If <code nobreak="false">external</code> is specified, then:</p>
                  <ulist>
                     <item>
                        <p>If the declaration occurs in a main module and a value is provided for the context value by the external environment, then
              the initial context value is
              that value, coerced to the required type as described below.</p>
                        <note>
                           <p>If the declaration occurs in a library module, then it does not set the 
                value of the initial context value, the value is set by the main module.</p>
                        </note>
                        <p>The means by which an external value is provided by the external environment is
              implementation-defined.</p>
                     </item>
                     <item>
                        <p>If no value is provided for the context value by the external environment, and
                <code nobreak="false">VarDefaultValue</code> is specified, then
                the initial context value is
                the result of evaluating
                <code nobreak="false">VarDefaultValue</code>, coerced to the required type as described below. </p>
                     </item>
                  </ulist>
               </item>
            </ulist>
            <!--<p>In all cases where the context value has a value, that value must match the type
        <code>T</code> according to the rules for SequenceType matching; otherwise a type error is
      raised <errorref class="TY" code="0004"/>. If more than one module contains a context value
      declaration, the context value must match the type declared in each one.</p>-->
            <p>If <code nobreak="false">VarValue</code> or <code nobreak="false">VarDefaultValue</code> is evaluated, the static and dynamic
      contexts for the evaluation are the current module's static and dynamic context.
      The static context for the initializing expression includes all functions, variables, and
      namespaces that are declared or imported anywhere in the Prolog.</p>
            <p>If a required type is defined in the main module, then the value obtained by 
      evaluating <code nobreak="false">VarValue</code> or <code nobreak="false">VarDefaultValue</code>, or the value supplied externally,
      is converted to the required type by applying
      the <termref def="dt-coercion-rules"/>. A type error occurs if this is not possible.
      In invoking the <termref def="dt-coercion-rules"/>, <termref def="dt-xpath-compat-mode"/> does not apply.</p>
            <p>If a required type is defined in any library module, then the value obtained by 
      evaluating <code nobreak="false">VarValue</code> or <code nobreak="false">VarDefaultValue</code>, or the value supplied externally,
      after coercion to any required type defined in the main module, must match that required
      type, without any further coercion; otherwise a type error is
      raised <errorref class="TY" code="0004"/>. If more than one library module contains a context value
      declaration, the context value must match the type declared in each one. </p>
            <p>Here are some examples of context value declarations.</p>
            <ulist>
               <item>
                  <p>Declare the type of the context value as a single element item with a required element name:</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare namespace env = "http://www.w3.org/2003/05/soap-envelope"; 
declare context item as element(env:Envelope) external;</eg>
               </item>
               <item>
                  <p>Declare a default context value, which is a system log in a default location. If the
          system log is in a different location, it can be specified in the external
          environment:</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare context value as element(sys:log) external :=
  doc("/var/xlogs/sysevent.xml")/sys:log; </eg>
               </item>
               <item>
                  <p>Declare a context value, which is collection whose collection URI is supplied as an external
          parameter to the query. If the
          system log is in a different location, it can be specified in the external
          environment:</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare variable $uri as xs:string external;
declare context value as document-node()* := collection($uri); </eg>
                  <p>With this declaration, a query body such as <code nobreak="false">//person[name="Mandela"]</code> returns all matching
        <code nobreak="false">person</code> elements appearing in any document in the collection.</p>
               </item>
            </ulist>
         </div2>
         <div2 id="FunctionDeclns">
            <head>Function Declarations</head>
            <changes>
               <change>
        Function definitions in the static context may now have optional parameters,
        provided this does not cause ambiguity across multiple function definitions with the same name.
        Optional parameters are given a default value, which can be any expression, including one that
        depends on the context of the caller (so an argument can default to the context value).
      </change>
               <change issue="657">
        A user-defined function whose name is given as an unprefixed QName is now in no namespace.
        In previous versions of the language, it represented a name in the <termref def="dt-default-function-namespace"/>
        (which only worked if the <termref def="dt-default-function-namespace"/> was explicitly set to an unreserved
        namespace, which was rarely done because it caused other problems).
      </change>
            </changes>
            <p diff="chg" at="variadicity">In addition to the <termref def="dt-system-function">system functions</termref>, XQuery
      allows users to declare functions of their own. A function declaration declares a family of functions
      having the same name and similar parameters. The declaration specifies the name of
      the function, the names and datatypes of the parameters, and the datatype of the result. All
      datatypes are specified using the syntax described in <specref ref="id-types"/>.</p>
            <p>Including a function declaration in the query causes a corresponding <termref def="dt-function-definition"/> to be
        added to the <termref def="dt-statically-known-function-definitions"/> of the <termref def="dt-static-context"/>.
        The associated functions also become available in the
        <termref def="dt-dynamically-known-function-definitions">dynamically known function definitions</termref> 
        of the <termref def="dt-dynamic-context"/>.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-FunctionDecl">
                  <lhs>FunctionDecl</lhs>
                  <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "function"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "("  <nt def="prod-xquery40-ParamListWithDefaults">ParamListWithDefaults<!--$idref_lang_part = xquery40- --></nt>?  ")"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  (<nt def="prod-xquery40-FunctionBody">FunctionBody<!--$idref_lang_part = xquery40- --></nt>  |  "external")</rhs>
                  <com>
                     <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-Annotation">
                  <lhs>Annotation</lhs>
                  <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-ParamListWithDefaults">
                  <lhs>ParamListWithDefaults</lhs>
                  <rhs>(<nt def="prod-xquery40-ParamWithDefault">ParamWithDefault<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-ParamWithDefault">
                  <lhs>ParamWithDefault</lhs>
                  <rhs>
                     <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  (":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-VarNameAndType">
                  <lhs>VarNameAndType</lhs>
                  <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-TypeDeclaration">
                  <lhs>TypeDeclaration</lhs>
                  <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-SequenceType">
                  <lhs>SequenceType</lhs>
                  <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-ExprSingle">
                  <lhs>ExprSingle</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-FunctionBody">
                  <lhs>FunctionBody</lhs>
                  <rhs>
                     <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-FunctionDecl-EnclosedExpr">
                  <lhs>EnclosedExpr</lhs>
                  <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
               </prod>
            </scrap>
            <p> A function declaration specifies whether the implementation of the function 
      is <termref def="dt-udf">user-defined</termref> or <termref def="dt-external-function">external</termref>.</p>
            <p>In addition to <termref def="dt-udf">user-defined functions</termref>
      and <termref def="dt-external-function">external functions</termref>, XQuery 4.0 allows anonymous
      functions to be declared in the body of a query using <termref def="dt-inline-func">inline function expressions</termref>.</p>
            <p>The following example illustrates the declaration and use of a local function that accepts a
      sequence of <code nobreak="false">employee</code> elements, summarizes them by department, and returns a
      sequence of <code nobreak="false">dept</code> elements.</p>
            <example>
               <head>Using a function, prepare a summary of employees that are located in Denver.</head>
               <eg role="parse-test" xml:space="preserve">declare function local:summary($emps as element(employee)*) as element(dept)* { 
  for $no in distinct-values($emps/deptno) 
  let $emp := $emps[deptno = $no]
  return &lt;dept&gt; 
    &lt;deptno&gt;{ $no }&lt;/deptno&gt; 
    &lt;headcount&gt;{ count($emp) }&lt;/headcount&gt; 
    &lt;payroll&gt;{ sum($emp/salary) }&lt;/payroll&gt; 
  &lt;/dept&gt; 
};
local:summary(doc("acme_corp.xml")//employee[location = "Denver"])</eg>
            </example>
            <div3 id="id-user-defined-functions">
               <head>User-Defined Functions</head>
               <p>
                  <termdef id="dt-udf" term="user-defined function">
                     <term>User defined functions</term> are functions that contain a <term>function body</term>,
          which provides the implementation of the function as a <termref def="dt-content-expression">content expression</termref>.</termdef> The
          <termref def="dt-static-context">static context</termref> for a function body includes all
        functions, variables, and namespaces that are declared or imported anywhere in the <termref def="dt-prolog">Prolog</termref>, including the function being declared. Its <termref def="dt-in-scope-variables">in-scope variables</termref> component also includes the
        parameters of the function being declared. </p>
               <p>An implementation <rfc2119>should</rfc2119> raise a static error <errorref class="ST" code="0008"/> if the function body depends on 
        the context value.
      </p>
               <p>The properties of the <termref def="dt-function-definition"/>
                  <var>F</var> are derived from the syntax of the
        function declaration as follows:</p>
               <ulist>
                  <item>
                     <p>The name of <var>F</var> is the <termref def="dt-expanded-qname"/> obtained by expanding the <code nobreak="false">EQName</code>
          that follows the keyword <code nobreak="false">function</code> as follows:</p>
                     <ulist>
                        <item>
                           <p>If the query module includes an explicit declaration of a <termref def="dt-default-function-namespace"/>,
            then the name is expanded using the <termref def="dt-default-function-namespace-rule"/>.
            That is, an unprefixed name represents a name in the default function namespace.</p>
                        </item>
                        <item>
                           <p>Otherwise (if the query module does not include an explicit declaration of a 
              <termref def="dt-default-function-namespace"/>), the name is expanded 
            using the <termref def="dt-no-namespace-rule"/>.
            That is, an unprefixed name represents a name in no namespace.</p>
                           <note>
                              <p>In previous XQuery versions this would generally be an error, because in the
            absence of an explicit default function namespace declaration, the default function
            namespace would generally be a <termref def="dt-reserved-namespaces">reserved namespace</termref>.</p>
                              <p>In 4.0, an unprefixed function name used in a static function call is resolved first
              by looking for a function in no namespace, and only if that fails to find a match, by looking
              for a function in the default function namespace.</p>
                           </note>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>The parameters of <var>F</var> are derived from the <code nobreak="false">ParamWithDefault</code> entries in the
          <code nobreak="false">ParamListWithDefaults</code>:</p>
                     <ulist>
                        <item>
                           <p>The parameter name is the <termref def="dt-expanded-qname"/> obtained by expanding the <code nobreak="false">EQName</code>
              that follows the <code nobreak="false">$</code> symbol using the <termref def="dt-no-namespace-rule"/>.</p>
                        </item>
                        <item>
                           <p>The required type of the parameter is given by the <code nobreak="false">TypeDeclaration</code>, defaulting to <code nobreak="false">item()*</code>.</p>
                        </item>
                        <item>
                           <p>The default value of the parameter is given by the expression that follows the <code nobreak="false">:=</code> symbol; if there
              is no default value, then the parameter is a required parameter.</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>The return type of the function is given by the final <code nobreak="false">TypeDeclaration</code> that follows the <code nobreak="false">ParamListWithDefaults</code>
          if present, defaulting to <code nobreak="false">item()*</code>.</p>
                  </item>
                  <item>
                     <p>The function annotations are derived from the annotations that follow the <code nobreak="false">%</code> symbol, if present.</p>
                  </item>
                  <item>
                     <p>The implementation of the function is given by the enclosed expression.</p>
                  </item>
               </ulist>
               <p>The static context may include more than one declared function with the same expanded name, but their arity ranges must 
        not overlap <errorref class="ST" code="0034"/>.</p>
               <note diff="add" at="2023-03-24">
                  <p>A consequence of this rule is that a function declaration must not declare a function that has arity 1 (one)
          if its name is the same as the name of an imported atomic type, since the name would then clash with the
          constructor function for that type.</p>
               </note>
            </div3>
            <div3 id="id-function-names">
               <head>Function Names</head>
               <changes>
                  <change issue="1954" PR="1956" date="2025-04-24">
          Private functions declared in a library module are no longer required to be in the module namespace.
        </change>
                  <change issue="657 2267" PR="2236">
          In the absence of a default namespace declaration, 
          a user-defined function whose name is given as an unprefixed QName is now in no namespace.
          In previous versions of the language, this would generally be an error.
        </change>
               </changes>
               <note>
                  <p>In XQuery 4.0 it is no longer the case that all declared functions must be in a namespace.
        If the function name is unprefixed, and there is no <termref def="dt-default-function-namespace"/>
        declaration, then it represents a no-namespace function name.</p>
               </note>
               <p>A <termref def="dt-public-function"/> 
        declared in a <termref def="dt-library-module">library module</termref> must be in
        the <termref def="dt-target-namespace">target namespace</termref> of the library module
        <errorref class="ST" code="0048"/>. </p>
               <p>
                  <termdef term="reserved namespaces" id="dt-reserved-namespaces">A <term>reserved namespace</term> is a namespace
        that must not be used in the name of a function declaration.</termdef>  
        It is a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0045"/> 
        if the function name in a function declaration (when expanded) is 
        in a <termref def="dt-reserved-namespaces">reserved namespace</termref>. 
        The following namespaces are reserved namespaces:
        <ulist>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/2001/XMLSchema-instance</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/2005/xpath-functions/array</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/2005/xpath-functions/map</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/2005/xpath-functions/math</code>
                        </p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">http://www.w3.org/2012/xquery</code>
                        </p>
                     </item>
                  </ulist>
               </p>
               <p>If the function name in a function declaration has no namespace prefix, it is matched as described
        at <specref ref="id-default-function-namespace-declaration"/>. In particular, if there is
      no default function namespace declaration, or if the default function namespace is given as
      an empty string, then the function is treated as being in no namespace.</p>
               <p>In order to allow modules to declare functions for local use within the module without
        defining a new namespace, and without any risk of conflicts with the 
        standard <code nobreak="false">fn</code> namespace, XQuery predefines the namespace prefix <code nobreak="false">local</code> to the
        namespace <code nobreak="false">http://www.w3.org/2005/xquery-local-functions</code>. It is suggested (but not
        required) that this namespace be used for defining local functions, including 
        <termref def="dt-private-function">private functions</termref> declared in 
        <termref def="dt-library-module">library modules</termref>.</p>
            </div3>
            <div3 id="id-function-parameters">
               <head>Function Parameters</head>
               <p>A function declaration includes a list of zero or more function parameters.</p>
               <p>The parameters of a function declaration are considered to be variables whose scope is the
        function body. It is an <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0039"/> for a function declaration to have more than one parameter
        with the same name. The type of a function parameter can be any type that can be expressed as
        a <termref def="dt-sequence-type">sequence type</termref>.</p>
               <p>If a function parameter is declared using a name but no type, its default type is
        <code nobreak="false">item()*</code>. If the result type is omitted from a function declaration, its default
        result type is <code nobreak="false">item()*</code>.</p>
               <p diff="add" at="variadicity">The function body defines the implementation of the <termref def="dt-function-definition"/>. 
        The rules for static function calls (see <specref ref="id-eval-static-function-call"/>)
        ensure that a value is available for each parameter, whether required or optional, and that the value
        will always be an instance of the declared type.
      </p>
               <p>A parameter is
    optional if a default value is supplied using the construct <code nobreak="false">:= ExprSingle</code>; otherwise it is required. If a parameter
    is optional, then all subsequent parameters in the list must also be optional; otherwise, a
    <termref def="dt-static-error">static error</termref> is raised <errorref class="ST" code="0148"/>.
    In other words, the parameter list includes
    zero or more required parameters followed by zero or more optional parameters.</p>
               <p>The number of arguments that may be supplied in a call to this family of functions is thus in the range <var>M</var> to <var>N</var>,
    where <var>M</var> is the number of required parameters, and <var>N</var> is the total number of parameters (whether required or optional).
    This is refered to as the <termref def="dt-arity-range"/> of the <termref def="dt-function-definition"/>.</p>
               <p diff="add" at="2023-05-19">The default value for an optional parameter will often be supplied using a 
       simple literal or constant expression, for example
     <code nobreak="false">$married as xs:boolean := false()</code> or <code nobreak="false">$options as map(*) := { }</code>. However, to allow greater flexibility,
     the initial value can also be context-dependent. For example, <code nobreak="false">$node as node() := .</code> declares a parameter whose
     default value is the context value from the dynamic context of the caller, while <code nobreak="false">$collation as xs:string := default-collation()</code>
     declares a parameter whose default value is the default collation from the dynamic context of the caller.
     The detailed rules are as follows. In these rules, the term <term>caller</term> means the function call or function reference
     that invokes the function being defined.</p>
               <p diff="add" at="2023-05-19">The <termref def="dt-static-context"/> for the initializing expression of an optional parameter is the same as the static
      context for the <termref def="dt-initializing-expression"/> of a variable declaration (see <specref ref="id-variable-declarations"/>),
      with the following exceptions:</p>
               <ulist diff="add" at="2023-05-19">
                  <item>
                     <p>The <termref def="dt-in-scope-variables"/> component is empty. This means that the 
          initializing expression cannot refer to any variables, other than local variables declared within the expression itself. 
          Note in particular that it cannot refer to other parameters of the function.</p>
                  </item>
                  <item>
                     <p>The <termref def="dt-statically-known-function-definitions"/> excludes all user-defined functions.</p>
                  </item>
               </ulist>
               <p diff="add" at="2023-05-19">The <termref def="dt-dynamic-context"/> for the initializing expression of an optional parameter 
        is the same as the dynamic context of the <term>caller</term>, with the following exceptions:</p>
               <ulist diff="add" at="2023-05-19">
                  <item>
                     <p>The <termref def="dt-variable-values"/> component is empty.</p>
                  </item>
                  <item>
                     <p>The <termref def="dt-dynamically-known-function-definitions"/> excludes all user-defined functions.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-function-annotations">
               <head>Function Annotations</head>
               <changes><!--<change PR="1137" issue="161" date="2024-04-23">
          Functions may be declared to be variadic.
        </change>
-->
                  <change issue="637 2058" PR="682 TODO" date="2025-06-24">
          The values <code nobreak="false">true()</code> and <code nobreak="false">false()</code> are allowed
          in function annotations, as well as negated numeric literals and
          QName literals.
        </change>
               </changes>
               <p>A function declaration may use the <code nobreak="false">%private</code> or <code nobreak="false">%public</code> annotations
      to specify that a function is public or private; if neither of these annotations is used, the
      function is public. <termdef id="dt-private-function" term="private function">A <term>private
          function</term> is a function with a <code nobreak="false">%private</code> annotation. A private function
        is hidden from <termref def="dt-module-import">module import</termref>, which can not import
        it into the <termref def="dt-statically-known-function-definitions"/> of another module. </termdef>
                  <termdef id="dt-public-function" term="public function">A <term>public function</term> is a
        function without a <code nobreak="false">%private</code> annotation. A public function is accessible to
          <termref def="dt-module-import">module import</termref>, which can import it into the
        <termref def="dt-statically-known-function-definitions"/> of
        another module. </termdef> Using <code nobreak="false">%public</code> and <code nobreak="false">%private</code> annotations
      in a main module is not an error, but it does not affect module imports, since a main module
      cannot be imported. It is a <termref def="dt-static-error">static error</termref>
                  <errorref class="ST" code="0106"/> if a function declaration contains both a
        <code nobreak="false">%private</code> and a <code nobreak="false">%public</code> annotation, more than one
        <code nobreak="false">%private</code> annotation, or more than one <code nobreak="false">%public</code> annotation. </p>
               <!--<p>The function annotation <code>%variadic</code> declares the corresponding
      <termref def="dt-function-definition"/> to be <termref def="dt-variadic"/>. If a function
        is annotated as <code>%variadic</code> then there must be at least one parameter,
      and all parameters including the final parameter must be required parameters
      <errorref spec="XQ" class="ST" code="0150"/>.
      For an overview of the behavior of variadic functions, see <specref ref="id-variadic-functions-overview"/>. </p>-->
               <p>An implementation can define annotations, in its own namespace, to support functionality
        beyond the scope of this specification. For instance, an implementation that supports external
        Java functions might use an annotation to associate a Java function with an XQuery external
        function:</p>
               <eg role="frag-prolog-parse-test" xml:space="preserve">declare 
  %java:method("java.lang.StrictMath.copySign") 
function smath:copySign($magnitude, $sign) external;</eg>
            </div3>
            <div3 id="id-external-functions">
               <head>External Functions</head>
               <p>
        In function declarations, <termref def="dt-external-function">external functions</termref> are identified by the keyword
        <code nobreak="false">external</code>. The purpose of a function declaration for an external function is to
        declare the datatypes of the function parameters and result, for use in type checking of the
        query that contains or imports the function declaration.</p>
               <p>An XQuery implementation may provide a facility whereby external functions can be implemented, 
      but it is not required to do so. If such a facility is
      provided, the protocols by which parameters are passed to an external function, and the result
      of the function is returned to the invoking query, are <termref def="dt-implementation-defined">implementation-defined</termref>. An XQuery implementation
      may augment the type system of <bibref ref="xpath-datamodel-40"/> with additional types that
      are designed to facilitate exchange of data, or it may provide
      mechanism for the user to define such types. For example, a type might be provided that
      encapsulates an object returned by an external function, such as an SQL database connection.
      </p>
               <p>An XQuery implementation <rfc2119>must</rfc2119> ensure that the resources available to external functions
      are restricted for security purposes, taking into account the extent to which the
      containing module is <termref def="dt-trusted"/>. If it is not possible to restrict
      the behavior of the external function, then access to the external function itself
      <rfc2119>must</rfc2119> be restricted.</p>
            </div3>
            <div3 id="id-recursion">
               <head>Recursion</head>
               <p>A function declaration may be recursive—that is, it may reference itself. Mutually
      recursive functions, whose bodies reference each other, are also allowed.</p>
               <example>
                  <head>A recursive function to compute the maximum depth of a document</head>
                  <p>The following
      example declares a recursive function that computes the maximum depth of a node hierarchy, and
      calls the function to find the maximum depth of a particular document. The function
        <code nobreak="false">local:depth</code> calls the built-in functions <code nobreak="false">empty</code> and
        <code nobreak="false">max</code>, which are in the default function namespace.</p>
                  <eg role="parse-test" xml:space="preserve">
declare function local:depth($e as node()) as xs:integer {
  (: A node with no children has depth 1 :)
  (: Otherwise, add 1 to max depth of children :)
  if (empty($e/*)) 
  then 1
  else max(for $c in $e/* return local:depth($c)) + 1
};

local:depth(doc("partlist.xml"))
        </eg>
                  <!-- ============================================================ -->
                  <p diff="add" at="variadicity">[TODO: add an example of a function with an optional parameter.]</p>
                  <!-- ============================================================ -->
               </example>
            </div3>
         </div2>
         <div2 id="id-item-type-declaration" diff="add" at="A">
            <head>Item Type Declarations</head>
            <p>An item type declaration defines a name for an <termref def="dt-item-type"/>. Defining a name for an item type
    allows it to be referenced by name rather than repeating
    the <termref def="dt-item-type-designator"/> in full.</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-ItemTypeDecl">
                  <lhs>ItemTypeDecl</lhs>
                  <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "type"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "as"  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemTypeDecl-Annotation">
                  <lhs>Annotation</lhs>
                  <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
               </prod>

               <prod id="doc-xquery40-ItemTypeDecl-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-ItemTypeDecl-ItemType">
                  <lhs>ItemType</lhs>
                  <rhs>
                     <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p>An item type declaration adds a <termref def="dt-named-item-type"/> to the <termref def="dt-in-scope-named-item-types"/>
    of the containing module. This enables the item type to be referred to using a simple name.</p>
            <example>
               <p>For example, given the declaration:</p>
               <eg xml:space="preserve">declare type app:invoice as map("xs:string", element(inv:paid-invoice));</eg>
               <p>It becomes possible to declare a variable containing a sequence of such items as:</p>
               <eg xml:space="preserve">declare variable $invoices as app:invoice*;</eg>
               <p>The definition can also be used within another item type declaration:</p>
               <eg xml:space="preserve">declare type app:overdue-invoices as map("xs:date", app:invoice*);</eg>
            </example>
            <p>If the name of the item type being declared is written as an (unprefixed) NCName, then 
      it is interpreted as being in the <termref def="dt-default-namespace-elements-and-types"/>.</p>
            <p>An item type declaration may use the <code nobreak="false">%private</code> or <code nobreak="false">%public</code> annotations
      to specify that an item type name is public or private; if neither of these annotations is used, the
      declaration is public.</p>
            <ulist>
               <item>
                  <p>
                     <termdef id="dt-private-item-type" term="private item type">A <term>private
        item type</term> is a named item type with a <code nobreak="false">%private</code> annotation. A private item type
        is hidden from <termref def="dt-module-import">module import</termref>, which can not import
        it into the <termref def="dt-in-scope-named-item-types"/> of another module. </termdef>
                  </p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-public-item-type" term="public item type">A <term>public item type</term> is an
         item type declaration without a <code nobreak="false">%private</code> annotation. A public item type is accessible to
        <termref def="dt-module-import">module import</termref>, which can import it into the
        <termref def="dt-in-scope-named-item-types"/> of
        another module. </termdef>
                  </p>
               </item>
               <item>
                  <p>Using <code nobreak="false">%public</code> and <code nobreak="false">%private</code> annotations
      in a main module is not an error, but it does not affect module imports, since a main module
      cannot be imported. </p>
               </item>
               <item>
                  <p>It is a <termref def="dt-static-error">static error</termref>
                     <errorref class="ST" code="0106"/> if an item type declaration contains both a
      <code nobreak="false">%private</code> and a <code nobreak="false">%public</code> annotation, more than one
      <code nobreak="false">%private</code> annotation, or more than one <code nobreak="false">%public</code> annotation. </p>
               </item>
               <item>
                  <p>The name of a <termref def="dt-public-item-type"/> declared in a <termref def="dt-library-module"/>
        must (when expanded) be in the <termref def="dt-target-namespace"/> of the 
      <termref def="dt-library-module"/>
                     <errorref class="ST" code="0048"/>.
      </p>
               </item>
               <item>
                  <p>The name of a <termref def="dt-private-item-type"/>, or of a <termref def="dt-public-item-type"/> declared
      in a <termref def="dt-main-module"/>, must be in a namespace, which may be any namespace
        that is not a <termref def="dt-reserved-namespaces">reserved namespace</termref>.</p>
                  <note>
                     <p>Writing the name as an unprefixed NCName is generally possible, except when the
      <termref def="dt-default-namespace-elements-and-types"/> is a reserved namespace.</p>
                  </note>
               </item>
            </ulist>
            <p>The declaration of an item type is available throughout the containing module; if it is
      public then it is also available throughout any importing modules. Forwards references are
      permitted, but cyclic and self-referential definitions are not allowed <errorref class="ST" code="0140"/>. This means that a reference to
      a named item type can always be replaced by the definition of the item type, but this can only happen after the item
      type declaration has been processed.</p>
            <p diff="add" at="issue275">The name of an item type must be unique among the names of all
      declared item types and <termref def="dt-generalized-atomic-type">generalized atomic types</termref>
      in the <termref def="dt-static-context"/> of the query module. <errorref class="ST" code="0146"/>
            </p>
            <note>
               <p>Named item types have been designed so that a reference to an item type name can be expanded
      (that is, replaced by its definition) as soon as the declaration is encountered during query parsing.
      There is never any need to retain item type names at execution time except optionally for diagnostics.</p>
            </note>
            <note>
               <p>The specification allows forwards references to named item type declarations. 
      While disallowing this would appear to make life easier for implementers, it is not practical because it
    would make cyclic module imports impossible.</p>
            </note>
            <note>
               <p>It is possible to import a public variable or function into a different module
    even if its declaration refers to named item types that are not themselves imported (because they
    are declared as <code nobreak="false">%private</code>). This is because the type name can always be replaced by 
    its definition. However, it is generally more convenient if any named item types used
    in public function and variable declarations are themselves public.</p>
            </note>
         </div2>
         <div2 id="id-named-record-types">
            <head>Named Record Types</head>
            <p>Although item type declarations, as described in <specref ref="id-item-type-declaration"/>, can be
    used to give names to record types as well as any other item type, named record types as described
    in this section provide a more concise syntax, plus additional functionality. In particular:</p>
            <ulist>
               <item>
                  <p>Named record types can be recursive.</p>
               </item>
               <item>
                  <p>Named record types implicitly create a constructor function that can be
        used to create instances of the record type.</p>
               </item>
               <item>
                  <p>A field in a named record type can be a function that has implicit access to
      the record on which it is defined, rather like methods in object-oriented languages.</p>
               </item>
            </ulist>
            <p>The syntax is as follows:</p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-NamedRecordTypeDecl">
                  <lhs>NamedRecordTypeDecl</lhs>
                  <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "record"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "("  (<nt def="prod-xquery40-ExtendedFieldDeclaration">ExtendedFieldDeclaration<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"</rhs>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-Annotation">
                  <lhs>Annotation</lhs>
                  <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-ExtendedFieldDeclaration">
                  <lhs>ExtendedFieldDeclaration</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FieldDeclaration">FieldDeclaration<!--$idref_lang_part = xquery40- --></nt>  (":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-FieldDeclaration">
                  <lhs>FieldDeclaration</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FieldName">FieldName<!--$idref_lang_part = xquery40- --></nt>  "?"?  ("as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-FieldName">
                  <lhs>FieldName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-SequenceType">
                  <lhs>SequenceType</lhs>
                  <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
               </prod>

               <prod id="doc-xquery40-NamedRecordTypeDecl-ExprSingle">
                  <lhs>ExprSingle</lhs>
                  <rhs>
                     <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                     <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>
            </scrap>
            <p>A named record declaration serves as both a <termref def="dt-named-item-type"/> and as a 
      <termref def="dt-function-definition"/>, and
      it therefore inherits rules from both these roles. In particular:</p>
            <olist>
               <item>
                  <p>Its name must not be the same as the name of any other named item type, or any
         generalized atomic type, that is present in the same static context <errorref class="ST" code="0048"/>.</p>
               </item>
               <item>
                  <p>If the declaration is public and is within a <termref def="dt-library-module"/>, then its name
       must be in the <termref def="dt-target-namespace"/> of the library module <errorref class="ST" code="0048"/>.
       </p>
               </item>
               <item>
                  <p>As a function, it must not have an arity range that overlaps the arity range of any
       other function declaration having the same name in the same static context.</p>
               </item>
               <item>
                  <p>The order of field declarations is significant, because it determines the order of
       arguments in a call to the constructor function.</p>
               </item>
               <item>
                  <p>The fields must have distinct names. <errorref class="ST" code="0021"/>
                  </p>
               </item>
               <item>
                  <p>In order to work as both a record type and a function declaration, the names of the
       fields must be simple NCNames in no namespace; the names must not be written as string literals
         <errorref class="ST" code="0003"/>.</p>
                  <note>
                     <p>This is described here as a semantic constraint, but an implementation might choose
       to impose it at the level of the grammar.</p>
                  </note>
               </item>
               <item>
                  <p>If an initializing expression is present in an <nt def="prod-xquery40-ExtendedFieldDeclaration">ExtendedFieldDeclaration<!--$spec = xquery40--></nt>, it must
       follow the rules for the initializing expression of a parameter in a function declaration,
       given in <specref ref="id-function-parameters"/>. In particular, if any field has an initializing
       expression then all following fields must have an initializing expression.</p>
               </item>
               <item>
                  <p>Any annotations that are present, such as <code nobreak="false">%public</code> or <code nobreak="false">%private</code>,
       apply both to the item type declaration and to the function declaration.</p>
               </item>
            </olist>
            <div3 id="named-records-as-item-types">
               <head>Named Records as Item Types</head>
               <p>As a named item type declaration, the construct:</p>
               <eg xml:space="preserve">declare record cx:complex(r as xs:double, i as xs:double := 0);</eg>
               <p>is equivalent to:</p>
               <eg xml:space="preserve">declare type cx:complex as record(r as xs:double, i as xs:double);</eg>
               <p>Any initializing expressions for fields are ignored for this purpose.</p>
               <note>
                  <p>The initializing expression only provides a default for values constructed using the 
          constructor function. It has no effect on the rules for determining whether a particular value is a valid instance
        of the type, and it does not affect the result of retrieval operations such as the lookup operator.</p>
               </note>
               <p>The name of a named record declaration is available throughout the static
          context of the module in which it is declared, including within the record declaration itself. This means that
          named record declarations can be self-recursive or mutually recursive.</p>
               <note>
                  <p>Unlike a named item type declared using <code nobreak="false">declare type</code>, a reference to a named record type
        cannot (in general) be directly replaced by the corresponding record definition during parsing, because
        in the case of a recursive definition, simple textual replacement would not terminate.</p>
               </note>
               <p>A recursive record type will only be instantiable if every field whose value may contain instances of the record type
        (directly or indirectly) is optional or emptiable. Specifically, it must either be an optional field, or its type
        declaration must be such that it can hold an empty sequence or a value of a different type. 
        A recursive record type that is not instantiable is considered to be <termref def="dt-implausible"/>, 
        which means that a processor may treat it as an error but is not obliged to do so <errorref class="ST" code="0023"/>.</p>
            </div3>
            <div3 id="named-records-as-functions">
               <head>Constructor Functions for Named Record Types</head>
               <changes>
                  <change issue="2365" PR="2413" date="2026-01-28">
            Extensible map types are dropped; instead, the coercion rules cause undefined
            map entries to be discarded.
         </change>
               </changes>
               <p>The construct:</p>
               <eg xml:space="preserve">declare record cx:complex(r as xs:double, i as xs:double := 0);</eg>
               <p>implicitly defines the function:</p>
               <eg xml:space="preserve">declare function cx:complex($r as xs:double, $i as xs:double := 0) as cx:complex {
  map:merge(({ "r": $r }, { "i": $i }))
};
       </eg>
               <p>So the call <code nobreak="false">cx:complex(3, 2)</code> produces the value <code nobreak="false">{ "r": 3e0, "i": 2e0 }</code>,
      while the call <code nobreak="false">cx:complex(3)</code> produces the value <code nobreak="false">{ "r": 3e0, "i": 0e0 }</code>
               </p>
               <p>The order of entries in the map corresponds
      to the order of field declarations in the record type. This means, for example, that when
      the map is serialized using the JSON output method, the order of entries in the output will
      correspond to the order of field declarations.</p>
               <p>If a field is declared as optional, by including a question mark after the name, and if it has no initializer,
      then the initializer <code nobreak="false">:= ()</code> is added implicitly. If the declared type of an optional field does
        not permit an empty sequence, then the declared type of the function parameter is adjusted by changing the
        occurrence indicator (from absent to <code nobreak="false">?</code> or from <code nobreak="false">+</code> to <code nobreak="false">*</code>) in order
      to make the empty sequence an acceptable value.</p>
               <p>Furthermore, if a field is optional and has no explicit initializer, the relevant entry in the constructed 
        map will be absent when the value supplied (implicitly or explicitly) to the function argument is an empty sequence. 
        This is achieved by modifying the function body. Given the declaration:</p>
               <eg xml:space="preserve">declare record cx:complex(r as xs:double, i? as xs:double);</eg>
               <p>the equivalent function declaration is:</p>
               <eg xml:space="preserve">declare function cx:complex($r as xs:double, $i as xs:double? := ()) as cx:complex {
  map:merge((
    { "r": $r },
    if (exists($i)) { { "i": $i } }
  ), { "retain-order" : true() })
};
       </eg>
               <p>If any field is either declared optional, or has an explicit initializer, 
        then all subsequent fields must also either be declared optional, or have an explicit initializer
        <errorref class="ST" code="0148"/>.</p>
               <p>More formally, the equivalent function declaration is derived as follows:</p>
               <ulist>
                  <item>
                     <p>The function annotations are the annotations on the named record declaration.</p>
                  </item>
                  <item>
                     <p>The function name is the QName of the named record declaration, expanded using
         the <termref def="dt-default-type-namespace-rule"/>. The resulting QName must be the same as the
       module namespace if the declaration appears in a library module, and in any event, it must be in some
       namespace.</p>
                  </item>
                  <item>
                     <p>The parameters of the function declaration are derived from the fields of the named record
       declaration, in order.</p>
                     <ulist>
                        <item>
                           <p>The name of the parameter is the name of the field (always an NCName).</p>
                        </item>
                        <item>
                           <p>The declared type of the parameter is the declared type of the field, if present; but
         if the field is optional, indicated by a question mark (<code nobreak="false">?</code>) after its name, and has no initializer,
           then the occurrence indicator is adjusted to permit an empty sequence, as described earlier.</p>
                        </item>
                        <item>
                           <p>The default value for the parameter is given by the initializing expression in
         the <nt def="prod-xquery40-ExtendedFieldDeclaration"><!--$spec = xquery40--></nt>, if present. If the field is optional and has no initializer, then
         it is given a default value of <code nobreak="false">()</code>, the empty sequence.</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>The return type of the function is the name of the record declaration, with no occurrence
       indicator.</p>
                  </item>
                  <item>
                     <p>The body of the function is a call of the function <code nobreak="false">map:merge</code> with two arguments:</p>
                     <ulist>
                        <item>
                           <p>The first argument is a parenthesized expression containing a 
             comma-separated sequence of subexpressions, containing one
           subexpression for each field, in order.</p>
                        </item>
                        <item>
                           <p>By default, the relevant subexpression is the map constructor <code nobreak="false">{ "N": $N }</code>
           where <var>N</var> is the field name.</p>
                        </item>
                        <item>
                           <p>If the field is optional and is declared without an explicit initializer, then the
           relevant subexpression takes the form <code nobreak="false">if (exists($N)) { { "N": $N } }</code>
           where <var>N</var> is the field name.</p>
                        </item>
                        <item>
                           <p>The second argument in the call of the function <code nobreak="false">map:merge</code>
           is the map <code nobreak="false">{ "duplicates": "use-first" }</code>.</p>
                        </item>
                     </ulist>
                  </item>
               </ulist>
               <p>Note that a question mark <code nobreak="false">?</code> after the field name indicates that the field is optional from the point of
       view of conformance of an item to the record type. The presence of an initializer indicates that it is optional
       from the point of view of a call on the constructor function. The two things are independent of each other. For example:</p>
               <ulist>
                  <item>
                     <p>
                        <code nobreak="false">record(longitude, latitude, altitude?)</code>
                     </p>
                     <p>Defines a record type in which <code nobreak="false">altitude</code> entry may be absent, and a constructor
           function with three arguments, of which the last is optional; if the function is called
           with two arguments (or with the third argument set to an empty sequence), then there will be no
           <code nobreak="false">altitude</code> entry in the resulting map.</p>
                     <p>
                        <code nobreak="false">record(longitude, latitude, altitude := 0)</code>
                     </p>
                     <p>Defines a record type in which all three fields will always be present, and a constructor
           function in which the third argument can be omitted, defaulting to zero.</p>
                     <p>
                        <code nobreak="false">record(longitude, latitude, altitude? := ())</code>
                     </p>
                     <p>Defines a record type in which the <code nobreak="false">altitude</code> entry may be absent both from the
             record and in the function call: but because a default value has been supplied explicitly,
             the constructed map will always have an entry for <code nobreak="false">altitude</code>.</p>
                  </item>
               </ulist>
               <note>
                  <p>Although the constructor function for a named record type produces a map in which the
        order of entries corresponds to the order of field declarations in the record type, the order
        of entries in a map is immaterial when testing whether a map matches the record type: the entries
        can be in any order.</p>
               </note>
            </div3>
            <div3 id="id-functions-as-fields">
               <head>Using Methods in Records</head>
               <p>Named record declarations are useful in conjunction with method calls, 
         described in <specref ref="id-methods"/>. For example, given the declaration:</p>
               <eg role="xquery" xml:space="preserve">
declare record my:rectangle (
   height as xs:double,
   width as xs:double,
   area as fn(my:rectangle) as xs:double 
     := fn{?height × ?width},
   resize as fn(my:rectangle, xs:double) as my:rectangle 
     := fn($rect, $factor) {
           $rect =&gt; map:put('height', $rect?height × $factor)
                 =&gt; map:put('width', $rect?width × $factor)
        }
);
               </eg>
               <p>The following expression constructs a rectangle and calculates its area:</p>
               <eg xml:space="preserve">let $box := my:rectangle(3, 2)
return $box =?&gt; area()</eg>
               <p>The following expands the dimensions of the rectangle and 
        calculates the perimeter of the result:</p>
               <eg xml:space="preserve">let $box := my:rectangle(3, 2)
return $box =?&gt; expand(2) =?&gt; perimeter()</eg>
               <note>
                  <p>There is nothing to stop a user constructing an instance of <code nobreak="false">my:rectangle</code>
     in which the <code nobreak="false">area</code> entry holds some different function: while the syntax imitates
     that of object-oriented languages, there is no encapsulation.</p>
               </note>
            </div3>
            <div3 id="id-atomic-set-example">
               <head>Example: Defining an Atomic Set</head>
               <p>This example demonstrates an XQuery library module that provides a new data type
               to manipulate sets of atomic items.</p>
               <p>A query that incorporates this module (by referencing
               it in an <code nobreak="false">import module</code> declaration) can use constructs such as:</p>
               <ulist>
                  <item>
                     <p>
                        <eg xml:space="preserve">declare variable $empty-set as set:atomic-set
    := set:build(());</eg>
                     </p>
                  </item>
                  <item>
                     <p>
                        <eg xml:space="preserve">declare variable $evens as set:atomic-set
    := set:build((1 to 100)[. mod 2 = 0]);</eg>
                     </p>
                  </item>
                  <item>
                     <p>
                        <eg xml:space="preserve">declare variable $odds as set:atomic-set
    := set:build((1 to 100)) =?&gt; except($evens)</eg>
                     </p>
                  </item>
                  <item>
                     <p>
                        <eg xml:space="preserve">declare function my:is-even ($n as xs:integer) as xs:boolean {
    $evens =?&gt; contains($n)
};</eg>
                     </p>
                  </item>
               </ulist>
               <p>Here is the implementation of the package. Methods are described in <specref ref="id-methods"/>.</p>
               <eg xml:space="preserve">
module namespace set = "http://qt4cg.org/atomic-set";
   
   (:
      This package defines a type set:atomic-set which represents
      a set of distinct atomic items. Atomic items are considered
      distinct based on the comparison function fn:atomic-equal.
      
      An instance of an atomic set can be constructed using a function
      call such as set:build((1, 3, 5, 7, 9)).
      
      If $A and $B are instances of set:atomic-set, then they
      can be manipulated using methods including:
      
      $A=?&gt;size() - returns the number of items in the set
      $A=?&gt;empty() - returns true if the set is empty
      $A=?&gt;contains($k) - determines whether $k is a member of the set
      $A=?&gt;contains-all($B) - returns true if $B is a subset of $A
      $A=?&gt;values() - returns the items in $A, as a sequence
      $A=?&gt;add($k) - returns a new atomic set containing an additional item
      $A=?&gt;remove($k) - returns a new atomic set in which the given item is absent
      $A=?&gt;union($B) - returns a new atomic set holding the union of $A and $B
      $A=?&gt;intersect($B) - returns a new atomic set holding the intersection of $A and $B
      $A=?&gt;except($B) - returns a new atomic set holding the difference of $A and $B
   :)
   
   declare %public record set:atomic-set (
       _data        as map(xs:anyAtomicType, xs:boolean),
       size         as fn($set as set:atomic-set) as xs:integer,
       empty        as fn($set as set:atomic-set) as xs:boolean,
       contains     as fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:boolean,
       contains-all as fn($set as set:atomic-set, $value as set:atomic-set) as xs:boolean,
       add          as fn($set as set:atomic-set, $item as xs:anyAtomicType) as set:atomic-set,
       remove       as fn($set as set:atomic-set, $item as xs:anyAtomicType) as set:atomic-set,
       union        as fn($set as set:atomic-set, $value as set:atomic-set) as set:atomic-set,
       intersect    as fn($set as set:atomic-set, $value as set:atomic-set) as set:atomic-set,
       except       as fn($set as set:atomic-set, $value as set:atomic-set) as set:atomic-set,
       * );

   declare %private variable DATA := "'_data'"; 
   
   (:
      The private function set:replaceData processes the internal map
      by applying a supplied function, and returns a new atomic set
      with the resulting internal map 
   :)
   
   declare %private function set:replaceData (
       $input as set:atomic-set,
       $update as fn(map(*)) as map(*)) as map(xs:anyAtomicType, xs:boolean) {
       
       map:put($input, $DATA, $update($input?$DATA))
   }
   
   declare %public function set:build (
       $values as xs:anyAtomicType* := ()) {
       
       {
         _data:
             map:build($values, values:=true#0, {'duplicates': 'use-first'}),
         size: fn($set as set:atomic-set) as xs:integer 
                     { map:size($set?$DATA) },
         empty: fn($set as set:atomic-set) as xs:boolean 
                     { map:empty($set?$DATA) },
         contains: fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:boolean 
                     { map:contains($set?$DATA, $value) },
         contains-all: fn($set as set:atomic-set, $other as set:atomic-set) as xs:boolean 
                     { every($other, map:contains($set?$DATA, ?)) },
         values: fn($set as set:atomic-set) as xs:anyAtomicType* 
                     { keys($set?$DATA) }"
         add: fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:anyAtomicType*
                     { set:replaceData($set, map:put(?, $value, true())) },
         remove: fn($set as set:atomic-set, $value as xs:anyAtomicType) as xs:anyAtomicType* 
                     { set:replaceData($set, map:remove(?, $value)) },
         union: fn($set as set:atomic-set, $other as set:atomic-set) as set:atomic-set 
                     { set:replaceData($set, fn($this) {map:merge(($this, $other?$DATA),
                                                    {'duplicates': 'use-first'})})
                     },
         intersect: fn($set as set:atomic-set, $other as set:atomic-set) as set:atomic-set 
                     { set:replaceData($set, map:filter(?, $other?contains)) },
         except: fn($set as set:atomic-set, $other as set:atomic-set) as set:atomic-set 
                     { set:replaceData($set, map:remove(?, $other?values())) }
      }
   };</eg>
               <ednote>
                  <edtext>The example is not yet tested. It could also be written
               using the new xsl:record instruction, which might be more concise.</edtext>
               </ednote>
            </div3>
         </div2>
         <div2 id="id-option-declaration">
            <head>Option Declarations</head>
            <p>
               <termdef term="option declaration" id="dt-option-declaration">An <term>option
          declaration</term> declares an option that affects the behavior of a particular
        implementation. Each option consists of an identifying EQName and a StringLiteral.</termdef>
            </p>
            <scrap headstyle="show">
               <prod id="doc-xquery40-OptionDecl">
                  <lhs>OptionDecl</lhs>
                  <rhs>"declare"  "option"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-OptionDecl-EQName">
                  <lhs>EQName</lhs>
                  <rhs>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
               </prod>

               <prod id="doc-xquery40-OptionDecl-StringLiteral">
                  <lhs>StringLiteral</lhs>
                  <rhs>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                  </rhs>
                  <com>
                     <loc href="#ws-explicit">ws: explicit</loc>
                  </com>
               </prod>
            </scrap>
            <p>Typically, a particular option will be recognized by some implementations and not by others.
      The syntax is designed so that option declarations can be successfully parsed by all
      implementations.</p>
            <p>If the EQName of an option is a <termref def="dt-qname">lexical QName</termref> then it is expanded
    using the <termref def="dt-default-annotation-namespace-rule"/>.</p>
            <note>
               <p>If the name is unprefixed, the <termref def="dt-expanded-qname">expanded QName</termref> will be in the <code nobreak="false">http://www.w3.org/2012/xquery</code> namespace,
      which is reserved for option declarations defined by the XQuery family of specifications.
      XQuery does not currently define declaration options in this namespace.</p>
            </note>
            <p>Each implementation recognizes the <code nobreak="false">http://www.w3.org/2012/xquery</code> namespace URI
      and and all options defined in this namespace in this specification. In addition, each
      implementation recognizes an <termref def="dt-implementation-defined">implementation-defined</termref> set of namespace URIs and an implementation-defined set of
      option names defined in those namespaces. If the namespace part of an option declaration's
      name is not recognized, the option declaration is ignored.</p>
            <p>Otherwise, the effect of the option declaration, including its error behavior, is <termref def="dt-implementation-defined">implementation-defined</termref>. For example, if the local
      part of the QName is not recognized, or if the StringLiteral does not conform to the rules
      defined by the implementation for the particular option declaration, the implementation may
      choose whether to raise an error, ignore the option declaration, or take some other
      action.</p>
            <p>Implementations may impose rules on where particular option declarations may appear relative
      to variable declarations and function declarations, and the interpretation of an option
      declaration may depend on its position.</p>
            <p>An option declaration must not be used to change the syntax accepted by the processor, or to
      suppress the detection of <termref def="dt-static-error">static errors</termref>. However, it
      may be used without restriction to modify the semantics of the query. The scope of the option
      declaration is <termref def="dt-implementation-defined">implementation-defined</termref>—for example, an option declaration might apply to the
      whole query, to the current module, or to the immediately following function declaration.</p>
            <p>The following examples illustrate several possible uses for option declarations:</p>
            <ulist>
               <item>
                  <p>This option declaration might be used to specify how comments in source documents
          returned by the <code nobreak="false">fn:doc()</code> function should be handled:</p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare option exq:strip-comments "true"; </eg>
               </item>
               <item>
                  <p>This option declaration might be used to associate a namespace used in function names
          with a Java class: </p>
                  <eg role="frag-prolog-parse-test" xml:space="preserve">declare namespace smath = "http://example.org/MathLibrary";
declare option exq:java-class "smath = java.lang.StrictMath"; </eg>
               </item>
            </ulist>
         </div2>
         <div2 id="id-output-declarations">
            <head>Output Declarations</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>
            <p role="xquery">
               <bibref ref="xslt-xquery-serialization-40"/> defines a set
of <term>serialization parameters</term> that govern the serialization
process. If an XQuery implementation provides a serialization
interface, it may support (and may expose to users) any of the
serialization parameters listed (with default values) in
in this section.
If an implementation does not support one of these parameters, it must ignore it without raising an error.</p>
            <p role="xquery">
               <termdef id="dt-output-declaration" term="output declaration">An <term>output declaration</term>
is an option declaration in the namespace <code nobreak="false">http://www.w3.org/2010/xslt-xquery-serialization</code>;
it is used to declare serialization parameters.</termdef>
Except for <code nobreak="false">parameter-document</code>, each option corresponds to a serialization parameter element defined in <xspecref spec="SE40" ref="serparams-schema"/>. 
The name of each option is the same as the name of the corresponding serialization parameter element, 
and the values permitted for each option are the same as the values allowed in the serialization parameter element. 
QName values are expanded using the <termref def="dt-default-element-namespace-rule"/>.</p>
            <p role="xquery">There is no output declaration for <code nobreak="false">use-character-maps</code>, it can be set only by means of a parameter document. 
When the application requests serialization of the output, the
processor may use these parameters to control the way in which the
serialization takes place.  Processors may also allow external
mechanisms for specifying serialization parameters, which may or may
not override serialization parameters specified in the query prolog.</p>
            <p>The following example illustrates the use of declaration options. </p>
            <example role="xquery">
               <eg role="frag-prolog-parse-test" xml:space="preserve">
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xml";
declare option output:encoding "iso-8859-1";
declare option output:indent "yes";
declare option output:parameter-document "file:///home/serialization-parameters.xml";
</eg>
            </example>
            <p role="xquery">An <term>output declaration</term> may appear only in a main module;
it is a static error  <errorref class="ST" code="0108"/> if an output declaration appears in a <termref def="dt-library-module">library module</termref>. 
It is a static error  <errorref class="ST" code="0110"/> if the same serialization parameter is declared more than once.
It is a <termref def="dt-static-error">static error</termref>
               <errorref class="ST" code="0109"/> if the local name of an
output declaration in the <code nobreak="false">http://www.w3.org/2010/xslt-xquery-serialization</code> namespace is not  one of the
serialization parameter names listed in <specref ref="id-xq-static-context-components"/> or <code nobreak="false">parameter-document</code>,
or if the name of an output declaration is <code nobreak="false">use-character-maps</code>. 
The default value for the <code nobreak="false">method</code> parameter is <code nobreak="false">"xml"</code>. An
implementation may define additional <termref def="dt-implementation-defined">implementation-defined</termref>
serialization parameters in its own namespaces.
</p>
            <p>Access to a parameter document as an external resource is possible only when either
      (a) the query is <termref def="dt-trusted"/>, or (b) the external resource in question
    has been explicitly made available by a <termref def="dt-trusted"/> caller.</p>
            <p role="xquery">If the local name of an output declaration in the
<code nobreak="false">http://www.w3.org/2010/xslt-xquery-serialization</code> namespace is
<code nobreak="false">parameter-document</code>, the value of the output declaration is treated as a
URI literal.  The value is a location hint, and identifies an XDM instance
in an implementation-defined way.  If a processor is performing
serialization, it is a static error <errorref class="ST" code="0119"/>  if the implementation
is not able to process the value of the
<code nobreak="false">output:parameter-document</code> declaration to produce an XDM instance.</p>
            <p role="xquery">If a processor is performing serialization, the XDM instance identified by
an <code nobreak="false">output:parameter-document</code> output declaration specifies the values of
serialization parameters in the manner defined by
<xspecref spec="SE40" ref="serparams-in-xdm-instance"/>.
It is a static error  <errorref class="ST" code="0115"/>  if this
yields a serialization error.  The value of any other output declaration
overrides any value that might have been specified for the same
serialization parameter using an output declaration in the
<code nobreak="false">http://www.w3.org/2010/xslt-xquery-serialization</code> namespace with the local name
parameter-document declaration.</p>
            <p role="xquery">A serialization parameter that is not applicable to the chosen output method
must be ignored, except that if its value is not a valid value for that
parameter, an error may be raised.</p>
            <p role="xquery">A processor that is performing serialization must raise a
serialization error if the values of any serialization parameters that it supports (other than any that are ignored under the previous paragraph) are
incorrect.</p>
            <p role="xquery">A processor that is not performing serialization may report errors if any
serialization parameters are incorrect, or may ignore such parameters.</p>
            <p role="xquery">Specifying serialization parameters in a query does not by itself demand
that the output be serialized. It merely defines the desired form of the
serialized output for use in situations where the processor has been asked
to perform serialization. </p>
            <note role="xquery">
               <p>The <termref def="dt-datamodel">data
model</termref> permits an element node to have
fewer <termref def="dt-in-scope-namespaces">in-scope
namespaces</termref> than its parent. Correct serialization of such an
element node would require “undeclaration” of namespaces, which is a
feature of <bibref ref="XMLNAMES11"/>. An implementation that does not
support <bibref ref="XMLNAMES11"/> is permitted to serialize such an
element without “undeclaration” of namespaces, which effectively
causes the element to inherit the in-scope namespaces of its
parent. </p>
            </note>
            <div3 id="id-serialization-parameters">
               <head>Serialization Parameters</head>
               <table width="100%" border="1" role="small">
                  <tbody>
                     <tr>
                        <th rowspan="1" colspan="1">Component</th>
                        <th rowspan="1" colspan="1">Default initial value</th>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">allow-duplicate-names</td>
                        <td rowspan="1" colspan="1">no</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">byte-order-mark</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">canonical</td>
                        <td rowspan="1" colspan="1">no</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">cdata-section-elements</td>
                        <td rowspan="1" colspan="1">empty</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">doctype-public</td>
                        <td rowspan="1" colspan="1">none</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">doctype-system</td>
                        <td rowspan="1" colspan="1">none</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">encoding</td>
                        <td rowspan="1" colspan="1">implementation-defined choice between <code nobreak="false">"UTF-8"</code> and <code nobreak="false">"UTF-16"</code>. Note that in names of encodings,
  upper and lower case are equivalent.</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">escape-solidus</td>
                        <td rowspan="1" colspan="1">yes</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">escape-uri-attributes</td>
                        <td rowspan="1" colspan="1">yes</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">html-version</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">include-content-type</td>
                        <td rowspan="1" colspan="1">yes</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">indent</td>
                        <td rowspan="1" colspan="1">no</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">item-separator</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">json-node-output-method</td>
                        <td rowspan="1" colspan="1">xml</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">media-type</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">method</td>
                        <td rowspan="1" colspan="1">xml</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">normalization-form</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">omit-xml-declaration</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">standalone</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">suppress-indentation</td>
                        <td rowspan="1" colspan="1">empty</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">undeclare-prefixes</td>
                        <td rowspan="1" colspan="1">no</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">use-character-maps</td>
                        <td rowspan="1" colspan="1">empty</td>
                     </tr>
                     <tr>
                        <td rowspan="1" colspan="1">version</td>
                        <td rowspan="1" colspan="1">implementation-defined</td>
                     </tr>
                  </tbody>
               </table>
            </div3>
         </div2>
      </div1>
      <div1 id="id-conformance">
         <head>Conformance</head>
         <changes>
            <change issue="205" PR="326" date="2023-02-01">
           Support for higher-order functions is now a mandatory feature (in 3.1 it was optional).
        </change>
            <change issue="1343" PR="1344" date="2024-09-03">
          The static typing feature has been dropped. 
        </change>
            <change issue="2022" PR="2026" date="2025-05-28" role="xquery">
          The module feature is no longer an optional feature; processing of library modules
          is now required.
        </change>
         </changes>
         <p>This section defines the conformance criteria for an XQuery 4.0 processor. In this section, the
        following terms are used to indicate the requirement levels defined in <bibref ref="RFC2119"/>. <termdef id="must" term="must">
               <term>MUST</term> means that the item is an absolute
            requirement of the specification.</termdef>
            <termdef id="mustnot" term="must not">
               <term>MUST NOT</term> means that the item is an
            absolute prohibition of the specification.</termdef>
            <termdef id="may" term="may">
               <term>MAY</term> means that an item is truly
            optional.</termdef>
            <termdef id="should" term="should" role="xquery">
               <term>SHOULD</term> means that there may exist valid
            reasons in particular circumstances to ignore a particular item, but the full
            implications must be understood and carefully weighed before choosing a different
            course.</termdef>
         </p>
         <p role="xquery">An XQuery processor that claims to conform to
      this specification <termref def="must">MUST</termref> include a
      claim of Minimal Conformance as defined in <specref ref="id-minimal-conformance"/>. In addition to a claim of
      Minimal Conformance, it <termref def="may">MAY</termref> claim
      conformance to one or more optional features defined in <specref ref="id-conform-optional-features"/>.</p>
         <div2 id="id-minimal-conformance" role="xquery">
            <head>Minimal Conformance</head>
            <p>An implementation that claims <term>Minimal Conformance</term> to this specification
                <termref def="must">MUST</termref> provide all of the following items:</p>
            <olist>
               <item>
                  <p>An implementation of everything specified in this document except those features
                    specified in <specref ref="id-conform-optional-features"/> to be optional. If an
                    implementation does not provide a given optional feature, it <termref def="must">MUST</termref> implement any requirements specified in <specref ref="id-conform-optional-features"/> for implementations that do not provide
                    that feature.</p>
               </item>
               <item>
                  <p>A definition of every item specified to be <termref def="dt-implementation-defined">implementation-defined</termref>, unless
                    that item is part of an optional feature that is not provided by the
                    implementation. A list of <termref def="dt-implementation-defined">implementation-defined</termref> items can be found in <specref ref="id-impl-defined-items"/>.</p>
                  <note>
                     <p>Implementations are not required to define items specified to be <termref def="dt-implementation-dependent">implementation-dependent</termref>.</p>
                  </note>
               </item>
               <item>
                  <p>An implementation of <bibref ref="xpath-datamodel-40"/>, as specified in <specref ref="id-data-model-conformance"/>, and a definition of every item specified
                    to be <termref def="dt-implementation-defined">implementation-defined</termref>,
                    unless that item is part of an optional feature that is not provided by the
                    implementation.</p>
               </item>
               <item>
                  <p>An implementation of all functions defined in <bibref ref="xpath-functions-40"/>,
                    and a definition of every item specified to be <termref def="dt-implementation-defined">implementation-defined</termref>, unless
                    that function or item is part of an optional feature that is not provided by the
                    implementation.</p>
               </item>
            </olist>
         </div2>
         <div2 id="id-conform-optional-features" role="xquery">
            <head>Optional Features</head>
            <p>The features discussed in this section are optional. An implementation <termref def="may">MAY</termref> claim conformance to one or more of these features.</p>
            <p>The description of each feature mentions any errors that occur if a query relies on a
            feature that is not present.</p>
            <div3 id="id-schema-aware-feature">
               <head>Schema Aware Feature</head>
               <p>
                  <termdef id="dt-schema-aware-feature" term="schema aware feature">The <term>Schema Aware Feature</term> permits the query Prolog to contain a
                        <termref def="dt-schema-import">schema import</termref>, and permits a query
                    to contain a <code nobreak="false">validate</code> expression (see <specref ref="id-validate"/>). </termdef>
               </p>
               <p>If an XQuery implementation does not provide the Schema Aware Feature, it <termref def="must">MUST</termref> raise a static error <errorref class="ST" code="0009"/> if it encounters a schema import, and it <termref def="must">MUST</termref> raise
                a static error <errorref class="ST" code="0075"/> if it encounters a
                    <code nobreak="false">validate</code> expression.</p>
               <p>If an implementation provides the Schema Aware Feature, it <termref def="must">MUST</termref> also provide the <specref ref="id-typed-data-feature"/>.</p>
            </div3>
            <div3 id="id-typed-data-feature">
               <head>Typed Data Feature</head>
               <p>
                  <termdef id="dt-typed-data-feature" term="typed data feature">The
                        <term>Typed Data Feature</term> permits an XDM instance to contain element
                    node types other than <code nobreak="false">xs:untyped</code> and attributes node types other
                    than <code nobreak="false">xs:untypedAtomic</code>.</termdef>
               </p>
               <p>If an XQuery implementation does not provide the Typed Data Feature, it <termref def="must">MUST</termref> guarantee that:</p>
               <olist>
                  <item>
                     <p>The XDM has the type <code nobreak="false">xs:untyped</code> for every element node and
                            <code nobreak="false">xs:untypedAtomic</code> for every attribute node, including nodes
                        created by the query.</p>
                  </item>
                  <item>
                     <p>Elements constructed by the query always have the type
                            <code nobreak="false">xs:untyped</code>; attributes constructed by the query always have
                        the type <code nobreak="false">xs:untypedAtomic</code>. (This is equivalent to using
                            <code nobreak="false">construction mode = strip</code>.)</p>
                  </item>
               </olist>
            </div3>
            <!--<div3 id="id-module-feature">
            <head>Module Feature</head>
            <p>
                <termdef id="dt-module-feature" term="module feature">The <term>Module
                        Feature</term> allows a query Prolog to contain a <term>Module Import</term>
                    and allows <term>library modules</term> to be created.</termdef>
            </p>
            <p>An implementation that does not provide the Module Feature <termref def="must"
                    >MUST</termref> raise a <termref def="dt-static-error">static error</termref>
                <errorref class="ST" code="0016"/> if it encounters a <termref
                    def="dt-module-declaration">module declaration</termref> or a <termref
                    def="dt-module-import">module import</termref>. Since a <termref
                    def="dt-module-declaration">module declaration</termref> is required in a
                    <termref def="dt-library-module">library module</termref>, the Module Feature is
                required in order to create a <termref def="dt-library-module">library module</termref>. </p>
            <note>
                <p>In the absence of the Module Feature, each query consists of a single <termref
                        def="dt-main-module">main module</termref>.</p>
            </note>
        </div3>-->
            <div3 id="id-serialization-feature">
               <head>Serialization Feature</head>
               <p>
                  <termdef id="dt-serialization-feature" term="serialization feature">The
                        <term>Serialization Feature</term> provides means for serializing the result
                    of a query as specified in <specref ref="id-serialization"/>.</termdef> A
                conforming XQuery implementation that provides the Serialization Feature <termref def="must">MUST</termref> conform to <specref ref="id-serialization"/>. An
                implementation <termref def="may">MAY</termref> provide other forms of
                serialization, which do not conform to the Serialization Feature, and are beyond the
                scope of this specification. </p>
               <p>The means by which serialization is invoked is <termref def="dt-implementation-defined">implementation-defined</termref>.</p>
               <p>If an error is raised during the serialization process as specified in <bibref ref="xslt-xquery-serialization-40"/>, an implementation <termref def="must">MUST</termref> report the error to the calling environment.</p>
               <p>An implementation that does not provide the Serialization Feature <termref def="must">MUST NOT</termref> raise errors when reading an <termref def="dt-output-declaration">output declaration</termref>, and <termref def="must">MUST</termref> implement <code nobreak="false">fn:serialize</code>; it <termref def="may">MAY</termref>, however, raise an error when <code nobreak="false">fn:serialize</code>
                is invoked, as specified in <xspecref spec="FO40" ref="func-serialize"/>. An
                implementation that does not provide the Serialization Feature <termref def="may">MAY</termref> provide results of a query using a vendor-defined
                serialization.</p>
               <note>
                  <p>Some implementations return query results without serialization. For instance, an
                    implementation might provide results via an XML API or a binary representation
                    such as a persistent DOM.</p>
               </note>
            </div3>
            <div3 id="id-higher-order-function-feature" diff="del" at="2023-01-29">
               <head>Higher-Order Function Feature</head>
               <p>
                The <term>Higher Order Function Feature</term> allows an expression to evaluate
                    to a function item other than a map or array.
            </p>
               <p>An implementation that does not provide the Higher-Order Function Feature <termref def="must">MUST</termref> raise a static error [...] if it encounters a  
                    <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$spec = xquery40--></nt>, <termref def="dt-named-function-ref">named function reference</termref>, <termref def="dt-inline-func">inline function expression</termref>, or <termref def="dt-partial-function-application">partial function application</termref>.  
                    The effect of this rule is that it is impossible to construct function items other than maps and arrays.
                    Dynamic function calls are permitted, but the function that is called will necessarily be a map or array.
                    The <nt def="prod-xquery40-AnyFunctionType">AnyFunctionType<!--$spec = xquery40--></nt>
                  <termref def="dt-sequence-type">sequence type</termref> is permitted and will match either a map 
                    or array.
                Such an implementation <termref def="may">MAY</termref> raise a type error <errorref class="TY" code="0004"/> if an expression evaluates to a sequence that contains
                a function.</p>
               <p>If an implementation provides the Higher-Order Function Feature, then it <termref def="must">MUST</termref> provide
                    all <xtermref spec="FO40" ref="dt-higher-order"/> functions defined in <bibref ref="xpath-functions-40"/>.
                If an implementation does not provide the Higher
                Order Function Feature, a <termref def="dt-static-error">static error</termref> is
                raised <errorref class="ST" code="0017"/> if any of these functions is present in a
                query. </p>
            </div3>
         </div2>
         <div2 id="id-data-model-conformance" role="xquery">
            <head>Data Model Conformance</head>
            <p>All XQuery implementations process data represented in the <termref def="dt-datamodel">data model</termref> as specified in <bibref ref="xpath-datamodel-40"/>. The data
            model specification relies on languages such as XQuery to specify conformance criteria
            for the data model in their respective environments, and suggests that the following
            issues should be considered:</p>
            <olist>
               <item>
                  <p>
                     <emph>Support for normative construction from an infoset.</emph> An
                    implementation <termref def="may">MAY</termref> choose to claim conformance to
                        <xspecref spec="DM40" ref="const-infoset"/>, which defines a normative way
                    to construct an <termref def="dt-data-model-instance">XDM instance</termref>
                    from an XML document that is merely well-formed or is governed by a DTD.</p>
               </item>
               <item>
                  <p>
                     <emph>Support for normative construction from a PSVI.</emph> An implementation
                        <termref def="may">MAY</termref> choose to claim conformance to <xspecref spec="DM40" ref="const-psvi"/>, which defines a normative way to construct
                    an <termref def="dt-data-model-instance">XDM instance</termref> from an XML
                    document that is governed by a W3C XML Schema.</p>
               </item>
               <item>
                  <p>
                     <emph>Support for versions of XML and XSD.</emph> As stated in <bibref ref="xpath-datamodel-40"/>, the
                    definitions of primitives such as strings, characters, and names 
                    are based on the definitions in XSD 1.1, though operations that require
                    use of an XML Schema processor <rfc2119>may</rfc2119> use an XSD 1.0 processor.
                    If new versions, editions, or errata are published for XML, XSD, or related specifications,
                    then implementations <rfc2119>may</rfc2119> adopt any changes.</p>
                  <note>
                     <p>For suggestions on processing XML 1.1 documents with XSD 1.0, see <bibref ref="xml11schema10"/>.</p>
                  </note>
               </item>
               <item>
                  <p>
                     <emph>Ranges of data values.</emph> 
                    Limits are defined in <xspecref spec="DM40" ref="atomic-type-limits"/>.</p>
                  <note>
                     <p>For discussion of errors due to <termref def="dt-implementation-dependent">implementation-dependent</termref> limits, see <specref ref="id-kinds-of-errors"/>.</p>
                  </note>
               </item>
            </olist>
         </div2>
         <div2 id="id-syntax-extensions" role="xquery">
            <head>Syntax Extensions</head>
            <p>Any syntactic extensions to XQuery are <termref def="dt-implementation-defined">implementation-defined</termref>. The effect of syntactic extensions, including
            their error behavior, is <termref def="dt-implementation-defined">implementation-defined</termref>. Syntactic extensions <termref def="may">MAY</termref> be used without
            restriction to modify the semantics of a XQuery expression.</p>
         </div2>
      </div1>
   </body>
   <back id="id-appendices">
      <div1 id="nt-bnf">
         <head>XQuery 4.0 Grammar</head>
         <div2 id="id-grammar">
            <head>EBNF</head>
            <changes>
               <change issue="1366" PR="1498">The EBNF operators <code nobreak="false">++</code> and <code nobreak="false">**</code>
      have been introduced, for more concise representation of sequences using a character
      such as <code nobreak="false">","</code> as a separator. The notation is borrowed from Invisible XML.</change>
            </changes>
            <p>The grammar of XQuery 4.0 uses the same simple Extended Backus-Naur Form (EBNF) notation as
        <bibref ref="XML"/> with the following differences.</p>
            <ulist>
               <item>
                  <p>The notation <code nobreak="false">XYZ ** ","</code> indicates a sequence of zero or more occurrences of
        <code nobreak="false">XYZ</code>, with a single comma between adjacent occurrences.</p>
               </item>
               <item>
                  <p>The notation <code nobreak="false">XYZ ++ ","</code> indicates a sequence of one or more occurrences of
        <code nobreak="false">XYZ</code>, with a single comma between adjacent occurrences.</p>
               </item>
               <item>
                  <p>All named symbols have a name that begins with an uppercase letter.</p>
               </item>
               <item>
                  <p>It adds a notation for referring to productions in external specifications.</p>
               </item>
               <item>
                  <p>Comments or extra-grammatical constraints on grammar productions are between '/*' and
          '*/' symbols.</p>
                  <ulist>
                     <item>
                        <p>A 'xgc:' prefix is an extra-grammatical constraint, the details of which are
              explained in <specref ref="extra-grammatical-constraints"/>
                        </p>
                     </item>
                     <item>
                        <p>A 'ws:' prefix explains the whitespace rules for the production, the details of which
              are explained in <specref ref="whitespace-rules"/>
                        </p>
                     </item>
                     <item>
                        <p>A 'gn:' prefix means a 'Grammar Note', and is meant as a clarification for parsing
              rules, and is explained in <specref ref="notes-on-parsing"/>. These notes are not
              normative.</p>
                     </item>
                  </ulist>
               </item>
            </ulist>
            <p>The terminal symbols for this grammar include the quoted strings used in the production rules
      below, and the terminal symbols defined in section <specref ref="terminal-symbols"/>.
    <phrase diff="add" at="2023-05-22">The grammar is a little unusual in that parsing and tokenization
    are somewhat intertwined: for more details see <specref ref="lexical-structure"/>.</phrase>
            </p>
            <p>The EBNF notation is described in more detail in <specref ref="EBNFNotation"/>.</p>
            <scrap id="BNF-Grammar"
                   role="non-terminal-structure-expand"
                   headstyle="show">
               <head/>
               <prodgroup>
                  <prod id="prod-xquery40-AbbreviatedStep">
                     <lhs>AbbreviatedStep</lhs>
                     <rhs>".."  |  ("@"  <nt def="doc-xquery40-NodeTest">NodeTest<!--$idref_lang_part = xquery40- --></nt>)  |  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-AbsolutePathExpr">
                     <lhs>AbsolutePathExpr</lhs>
                     <rhs>("/"  <nt def="prod-xquery40-RelativePathExpr">RelativePathExpr<!--$idref_lang_part = xquery40- --></nt>?)  |  ("//"  <nt def="prod-xquery40-RelativePathExpr">RelativePathExpr<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-AdditiveExpr">
                     <lhs>AdditiveExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>  (("+"  |  "-")  <nt def="prod-xquery40-MultiplicativeExpr">MultiplicativeExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-AllowingEmpty">
                     <lhs>AllowingEmpty</lhs>
                     <rhs>"allowing"  "empty"</rhs>
                  </prod>

                  <prod id="prod-xquery40-AndExpr">
                     <lhs>AndExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ComparisonExpr">ComparisonExpr<!--$idref_lang_part = xquery40- --></nt>  ("and"  <nt def="prod-xquery40-ComparisonExpr">ComparisonExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-Annotation">
                     <lhs>Annotation</lhs>
                     <rhs>"%"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ("("  (<nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")")?</rhs>
                  </prod>

                  <prod id="prod-xquery40-AnyArrayType">
                     <lhs>AnyArrayType</lhs>
                     <rhs>"array"  "("  "*"  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-AnyFunctionType">
                     <lhs>AnyFunctionType</lhs>
                     <rhs>("function"  |  "fn")  "("  "*"  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-AnyItemType">
                     <lhs>AnyItemType</lhs>
                     <rhs>"item"  "("  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-AnyMapType">
                     <lhs>AnyMapType</lhs>
                     <rhs>"map"  "("  "*"  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-AnyXNodeType">
                     <lhs>AnyXNodeType</lhs>
                     <rhs>"node"  "("  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-AposAttrValueContent">
                     <lhs>AposAttrValueContent</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AposAttrContentChar">AposAttrContentChar<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CommonContent">CommonContent<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Argument">
                     <lhs>Argument</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArgumentPlaceholder">ArgumentPlaceholder<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ArgumentList">
                     <lhs>ArgumentList</lhs>
                     <rhs>"("  ((<nt def="prod-xquery40-PositionalArguments">PositionalArguments<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-KeywordArguments">KeywordArguments<!--$idref_lang_part = xquery40- --></nt>)?)  |  <nt def="prod-xquery40-KeywordArguments">KeywordArguments<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-ArgumentPlaceholder">
                     <lhs>ArgumentPlaceholder</lhs>
                     <rhs>"?"</rhs>
                  </prod>

                  <prod id="prod-xquery40-ArrayConstructor">
                     <lhs>ArrayConstructor</lhs>
                     <rhs>
                        <nt def="prod-xquery40-SquareArrayConstructor">SquareArrayConstructor<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CurlyArrayConstructor">CurlyArrayConstructor<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ArrayType">
                     <lhs>ArrayType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AnyArrayType">AnyArrayType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypedArrayType">TypedArrayType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ArrowExpr">
                     <lhs>ArrowExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-UnaryExpr">UnaryExpr<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-SequenceArrowTarget">SequenceArrowTarget<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MappingArrowTarget">MappingArrowTarget<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-ArrowTarget">
                     <lhs>ArrowTarget</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FunctionCall">FunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-RestrictedDynamicCall">RestrictedDynamicCall<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-AttributeName">
                     <lhs>AttributeName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-AttributeNodeType">
                     <lhs>AttributeNodeType</lhs>
                     <rhs>"attribute"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-Axis">
                     <lhs>Axis</lhs>
                     <rhs>("ancestor"  |  "ancestor-or-self"  |  "attribute"  |  "child"  |  "descendant"  |  "descendant-or-self"  |  "following"  |  "following-or-self"  |  "following-sibling"  |  "following-sibling-or-self"  |  "parent"  |  "preceding"  |  "preceding-or-self"  |  "preceding-sibling"  |  "preceding-sibling-or-self"  |  "self")  "::"</rhs>
                  </prod>

                  <prod id="prod-xquery40-AxisStep">
                     <lhs>AxisStep</lhs>
                     <rhs>(<nt def="doc-xquery40-AbbreviatedStep">AbbreviatedStep<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FullStep">FullStep<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-Predicate">Predicate<!--$idref_lang_part = xquery40- --></nt>*</rhs>
                  </prod>

                  <prod id="prod-xquery40-BaseURIDecl">
                     <lhs>BaseURIDecl</lhs>
                     <rhs>"declare"  "base-uri"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-BoundarySpaceDecl">
                     <lhs>BoundarySpaceDecl</lhs>
                     <rhs>"declare"  "boundary-space"  ("preserve"  |  "strip")</rhs>
                  </prod>

                  <prod id="prod-xquery40-BracedAction">
                     <lhs>BracedAction</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-BracedSwitchCases">
                     <lhs>BracedSwitchCases</lhs>
                     <rhs>"{"  <nt def="prod-xquery40-SwitchCases">SwitchCases<!--$idref_lang_part = xquery40- --></nt>  "}"</rhs>
                  </prod>

                  <prod id="prod-xquery40-BracedTypeswitchCases">
                     <lhs>BracedTypeswitchCases</lhs>
                     <rhs>"{"  <nt def="prod-xquery40-TypeswitchCases">TypeswitchCases<!--$idref_lang_part = xquery40- --></nt>  "}"</rhs>
                  </prod>

                  <prod id="prod-xquery40-CaseClause">
                     <lhs>CaseClause</lhs>
                     <rhs>"case"  (<nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>  "as")?  <nt def="prod-xquery40-SequenceTypeUnion">SequenceTypeUnion<!--$idref_lang_part = xquery40- --></nt>  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CastableExpr">
                     <lhs>CastableExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CastExpr">CastExpr<!--$idref_lang_part = xquery40- --></nt>  ("castable"  "as"  <nt def="prod-xquery40-CastTarget">CastTarget<!--$idref_lang_part = xquery40- --></nt>  "?"?)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-CastExpr">
                     <lhs>CastExpr</lhs>
                     <rhs>
                        <nt def="doc-xquery40-PipelineExpr">PipelineExpr<!--$idref_lang_part = xquery40- --></nt>  ("cast"  "as"  <nt def="prod-xquery40-CastTarget">CastTarget<!--$idref_lang_part = xquery40- --></nt>  "?"?)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-CastTarget">
                     <lhs>CastTarget</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EnumerationType">EnumerationType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CatchClause">
                     <lhs>CatchClause</lhs>
                     <rhs>"catch"  <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CDataSection">
                     <lhs>CDataSection</lhs>
                     <rhs>"&lt;![CDATA["  <nt def="prod-xquery40-CDataSectionContents">CDataSectionContents<!--$idref_lang_part = xquery40- --></nt>  "]]&gt;"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-CDataSectionContents">
                     <lhs>CDataSectionContents</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* ']]&gt;' Char*))</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-ChoiceItemType">
                     <lhs>ChoiceItemType</lhs>
                     <rhs>"("  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt> ++ "|")  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-CommentNodeType">
                     <lhs>CommentNodeType</lhs>
                     <rhs>"comment"  "("  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-CommonContent">
                     <lhs>CommonContent</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  "{{"  |  "}}"  |  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ComparisonExpr">
                     <lhs>ComparisonExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-OtherwiseExpr">OtherwiseExpr<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-ValueComp">ValueComp<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-GeneralComp">GeneralComp<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NodeComp">NodeComp<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-OtherwiseExpr">OtherwiseExpr<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-CompAttrConstructor">
                     <lhs>CompAttrConstructor</lhs>
                     <rhs>"attribute"  <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CompCommentConstructor">
                     <lhs>CompCommentConstructor</lhs>
                     <rhs>"comment"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CompDocConstructor">
                     <lhs>CompDocConstructor</lhs>
                     <rhs>"document"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CompElemConstructor">
                     <lhs>CompElemConstructor</lhs>
                     <rhs>"element"  <nt def="prod-xquery40-CompNodeName">CompNodeName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedContentExpr">EnclosedContentExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CompNamespaceConstructor">
                     <lhs>CompNamespaceConstructor</lhs>
                     <rhs>"namespace"  <nt def="prod-xquery40-CompNodeNCName">CompNodeNCName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CompNodeName">
                     <lhs>CompNodeName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-UnreservedName">UnreservedName<!--$idref_lang_part = xquery40- --></nt>  |  ("{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}")</rhs>
                  </prod>

                  <prod id="prod-xquery40-CompNodeNCName">
                     <lhs>CompNodeNCName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-MarkedNCName">MarkedNCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-UnreservedNCName">UnreservedNCName<!--$idref_lang_part = xquery40- --></nt>  |  ("{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}")</rhs>
                  </prod>

                  <prod id="prod-xquery40-CompPIConstructor">
                     <lhs>CompPIConstructor</lhs>
                     <rhs>"processing-instruction"  <nt def="prod-xquery40-CompNodeNCName">CompNodeNCName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CompTextConstructor">
                     <lhs>CompTextConstructor</lhs>
                     <rhs>"text"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ComputedConstructor">
                     <lhs>ComputedConstructor</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CompDocConstructor">CompDocConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompElemConstructor">CompElemConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompAttrConstructor">CompAttrConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompNamespaceConstructor">CompNamespaceConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompTextConstructor">CompTextConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompCommentConstructor">CompCommentConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CompPIConstructor">CompPIConstructor<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Constant">
                     <lhs>Constant</lhs>
                     <rhs>
                        <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("-"?  <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>)  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>  |  ("true"  "("  ")")  |  ("false"  "("  ")")</rhs>
                  </prod>

                  <prod id="prod-xquery40-ConstructionDecl">
                     <lhs>ConstructionDecl</lhs>
                     <rhs>"declare"  "construction"  ("strip"  |  "preserve")</rhs>
                  </prod>

                  <prod id="prod-xquery40-ContextValueDecl">
                     <lhs>ContextValueDecl</lhs>
                     <rhs>"declare"  "context"  (("value"  ("as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?)  |  ("item"  ("as"  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>)?))  ((":="  <nt def="prod-xquery40-VarValue">VarValue<!--$idref_lang_part = xquery40- --></nt>)  |  ("external"  (":="  <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$idref_lang_part = xquery40- --></nt>)?))</rhs>
                  </prod>

                  <prod id="prod-xquery40-ContextValueRef">
                     <lhs>ContextValueRef</lhs>
                     <rhs>"."</rhs>
                  </prod>

                  <prod id="prod-xquery40-CopyNamespacesDecl">
                     <lhs>CopyNamespacesDecl</lhs>
                     <rhs>"declare"  "copy-namespaces"  <nt def="prod-xquery40-PreserveMode">PreserveMode<!--$idref_lang_part = xquery40- --></nt>  ","  <nt def="prod-xquery40-InheritMode">InheritMode<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CountClause">
                     <lhs>CountClause</lhs>
                     <rhs>"count"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CurlyArrayConstructor">
                     <lhs>CurlyArrayConstructor</lhs>
                     <rhs>"array"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-CurrentVar">
                     <lhs>CurrentVar</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-DecimalFormatDecl">
                     <lhs>DecimalFormatDecl</lhs>
                     <rhs>"declare"  (("decimal-format"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>)  |  ("default"  "decimal-format"))  (<nt def="prod-xquery40-DFPropertyName">DFPropertyName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-DefaultCollationDecl">
                     <lhs>DefaultCollationDecl</lhs>
                     <rhs>"declare"  "default"  "collation"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-DefaultNamespaceDecl">
                     <lhs>DefaultNamespaceDecl</lhs>
                     <rhs>"declare"  "fixed"?  "default"  ("element"  |  "function")  "namespace"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-DFPropertyName">
                     <lhs>DFPropertyName</lhs>
                     <rhs>"decimal-separator"  |  "grouping-separator"  |  "infinity"  |  "minus-sign"  |  "NaN"  |  "percent"  |  "per-mille"  |  "zero-digit"  |  "digit"  |  "pattern-separator"  |  "exponent-separator"</rhs>
                  </prod>

                  <prod id="prod-xquery40-DirAttributeList">
                     <lhs>DirAttributeList</lhs>
                     <rhs>(<nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>?  "="  <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-DirAttributeValue">DirAttributeValue<!--$idref_lang_part = xquery40- --></nt>)?)*</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DirAttributeValue">
                     <lhs>DirAttributeValue</lhs>
                     <rhs>('"'  (<nt def="prod-xquery40-EscapeQuot">EscapeQuot<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotAttrValueContent">QuotAttrValueContent<!--$idref_lang_part = xquery40- --></nt>)*  '"')<br/>|  ("'"  (<nt def="prod-xquery40-EscapeApos">EscapeApos<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-AposAttrValueContent">AposAttrValueContent<!--$idref_lang_part = xquery40- --></nt>)*  "'")</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DirCommentConstructor">
                     <lhs>DirCommentConstructor</lhs>
                     <rhs>"&lt;!--"  <nt def="prod-xquery40-DirCommentContents">DirCommentContents<!--$idref_lang_part = xquery40- --></nt>  "--&gt;"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DirCommentContents">
                     <lhs>DirCommentContents</lhs>
                     <rhs>((<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - '-')  |  ("-"  (<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - '-')))*</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DirectConstructor">
                     <lhs>DirectConstructor</lhs>
                     <rhs>
                        <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-DirCommentConstructor">DirCommentConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-DirPIConstructor">DirPIConstructor<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-DirElemConstructor">
                     <lhs>DirElemConstructor</lhs>
                     <rhs>"&lt;"  <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-DirAttributeList">DirAttributeList<!--$idref_lang_part = xquery40- --></nt>  ("/&gt;"  |  ("&gt;"  <nt def="prod-xquery40-DirElemContent">DirElemContent<!--$idref_lang_part = xquery40- --></nt>*  "&lt;/"  <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>?  "&gt;"))</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DirElemContent">
                     <lhs>DirElemContent</lhs>
                     <rhs>
                        <nt def="prod-xquery40-DirectConstructor">DirectConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CDataSection">CDataSection<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CommonContent">CommonContent<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-ElementContentChar">ElementContentChar<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-DirPIConstructor">
                     <lhs>DirPIConstructor</lhs>
                     <rhs>"&lt;?"  <nt def="prod-xquery40-PITarget">PITarget<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-DirPIContents">DirPIContents<!--$idref_lang_part = xquery40- --></nt>)?  "?&gt;"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DirPIContents">
                     <lhs>DirPIContents</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* '?&gt;' Char*))</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DocumentNodeType">
                     <lhs>DocumentNodeType</lhs>
                     <rhs>"document-node"  "("  (<nt def="prod-xquery40-ElementNodeType">ElementNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SchemaElementNodeType">SchemaElementNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-DynamicFunctionCall">
                     <lhs>DynamicFunctionCall</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ElementName">
                     <lhs>ElementName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ElementNodeType">
                     <lhs>ElementNodeType</lhs>
                     <rhs>"element"  "("  (<nt def="prod-xquery40-NameTestUnion">NameTestUnion<!--$idref_lang_part = xquery40- --></nt>  (","  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  "?"?)?)?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-EmptyOrderDecl">
                     <lhs>EmptyOrderDecl</lhs>
                     <rhs>"declare"  "default"  "order"  "empty"  ("greatest"  |  "least")</rhs>
                  </prod>

                  <prod id="prod-xquery40-EnclosedContentExpr">
                     <lhs>EnclosedContentExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-EnclosedExpr">
                     <lhs>EnclosedExpr</lhs>
                     <rhs>"{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                  </prod>

                  <prod id="prod-xquery40-EnumerationType">
                     <lhs>EnumerationType</lhs>
                     <rhs>"enum"  "("  (<nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-EQName">
                     <lhs>EQName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Expr">
                     <lhs>Expr</lhs>
                     <rhs>(<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-ExprSingle">
                     <lhs>ExprSingle</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FLWORExpr">FLWORExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-QuantifiedExpr">QuantifiedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SwitchExpr">SwitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypeswitchExpr">TypeswitchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-IfExpr">IfExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TryCatchExpr">TryCatchExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrExpr">OrExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ExtendedFieldDeclaration">
                     <lhs>ExtendedFieldDeclaration</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FieldDeclaration">FieldDeclaration<!--$idref_lang_part = xquery40- --></nt>  (":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-ExtensionExpr">
                     <lhs>ExtensionExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Pragma">Pragma<!--$idref_lang_part = xquery40- --></nt>+  "{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}"</rhs>
                  </prod>

                  <prod id="prod-xquery40-FieldDeclaration">
                     <lhs>FieldDeclaration</lhs>
                     <rhs>
                        <nt def="prod-xquery40-FieldName">FieldName<!--$idref_lang_part = xquery40- --></nt>  "?"?  ("as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-FieldName">
                     <lhs>FieldName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-FilterExpr">
                     <lhs>FilterExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-Predicate">Predicate<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-FilterExprAM">
                     <lhs>FilterExprAM</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  "?["  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "]"</rhs>
                  </prod>

                  <prod id="prod-xquery40-FinallyClause">
                     <lhs>FinallyClause</lhs>
                     <rhs>"finally"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-FLWORExpr">
                     <lhs>FLWORExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-InitialClause">InitialClause<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-IntermediateClause">IntermediateClause<!--$idref_lang_part = xquery40- --></nt>*  <nt def="prod-xquery40-ReturnClause">ReturnClause<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ForBinding">
                     <lhs>ForBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ForItemBinding">ForItemBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ForMemberBinding">ForMemberBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ForEntryBinding">ForEntryBinding<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ForClause">
                     <lhs>ForClause</lhs>
                     <rhs>"for"  (<nt def="prod-xquery40-ForBinding">ForBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-ForEntryBinding">
                     <lhs>ForEntryBinding</lhs>
                     <rhs>((<nt def="prod-xquery40-ForEntryKeyBinding">ForEntryKeyBinding<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-ForEntryValueBinding">ForEntryValueBinding<!--$idref_lang_part = xquery40- --></nt>?)  |  <nt def="prod-xquery40-ForEntryValueBinding">ForEntryValueBinding<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ForEntryKeyBinding">
                     <lhs>ForEntryKeyBinding</lhs>
                     <rhs>"key"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ForEntryValueBinding">
                     <lhs>ForEntryValueBinding</lhs>
                     <rhs>"value"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ForItemBinding">
                     <lhs>ForItemBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-AllowingEmpty">AllowingEmpty<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ForMemberBinding">
                     <lhs>ForMemberBinding</lhs>
                     <rhs>"member"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-FullStep">
                     <lhs>FullStep</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Axis">Axis<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="doc-xquery40-NodeTest">NodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-FunctionBody">
                     <lhs>FunctionBody</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-FunctionCall">
                     <lhs>FunctionCall</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-ArgumentList">ArgumentList<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                     </com>
                     <com>
                        <loc href="#parse-note-parens">gn: parens</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-FunctionDecl">
                     <lhs>FunctionDecl</lhs>
                     <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "function"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "("  <nt def="prod-xquery40-ParamListWithDefaults">ParamListWithDefaults<!--$idref_lang_part = xquery40- --></nt>?  ")"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  (<nt def="prod-xquery40-FunctionBody">FunctionBody<!--$idref_lang_part = xquery40- --></nt>  |  "external")</rhs>
                     <com>
                        <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-FunctionItemExpr">
                     <lhs>FunctionItemExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-NamedFunctionRef">NamedFunctionRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-InlineFunctionExpr">InlineFunctionExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-FunctionSignature">
                     <lhs>FunctionSignature</lhs>
                     <rhs>"("  <nt def="prod-xquery40-ParamList">ParamList<!--$idref_lang_part = xquery40- --></nt>  ")"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="prod-xquery40-FunctionType">
                     <lhs>FunctionType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  (<nt def="prod-xquery40-AnyFunctionType">AnyFunctionType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TypedFunctionType">TypedFunctionType<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-GeneralComp">
                     <lhs>GeneralComp</lhs>
                     <rhs>"="  |  "!="  |  "&lt;"  |  "&lt;="  |  "&gt;"  |  "&gt;="</rhs>
                  </prod>

                  <prod id="prod-xquery40-GNodeType">
                     <lhs>GNodeType</lhs>
                     <rhs>"gnode"  "("  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-GroupByClause">
                     <lhs>GroupByClause</lhs>
                     <rhs>"group"  "by"  (<nt def="prod-xquery40-GroupingSpec">GroupingSpec<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-GroupingSpec">
                     <lhs>GroupingSpec</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?  ("collation"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-IfExpr">
                     <lhs>IfExpr</lhs>
                     <rhs>"if"  "("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  ")"  (<nt def="prod-xquery40-UnbracedActions">UnbracedActions<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedAction">BracedAction<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-Import">
                     <lhs>Import</lhs>
                     <rhs>
                        <nt def="prod-xquery40-SchemaImport">SchemaImport<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ModuleImport">ModuleImport<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-InheritMode">
                     <lhs>InheritMode</lhs>
                     <rhs>"inherit"  |  "no-inherit"</rhs>
                  </prod>

                  <prod id="prod-xquery40-InitialClause">
                     <lhs>InitialClause</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ForClause">ForClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetClause">LetClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-WindowClause">WindowClause<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-InlineFunctionExpr">
                     <lhs>InlineFunctionExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  ("function"  |  "fn")  <nt def="prod-xquery40-FunctionSignature">FunctionSignature<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-FunctionBody">FunctionBody<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-InstanceofExpr">
                     <lhs>InstanceofExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TreatExpr">TreatExpr<!--$idref_lang_part = xquery40- --></nt>  ("instance"  "of"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-IntermediateClause">
                     <lhs>IntermediateClause</lhs>
                     <rhs>
                        <nt def="prod-xquery40-InitialClause">InitialClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-WhereClause">WhereClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-WhileClause">WhileClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-GroupByClause">GroupByClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-OrderByClause">OrderByClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CountClause">CountClause<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-IntersectExceptExpr">
                     <lhs>IntersectExceptExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-InstanceofExpr">InstanceofExpr<!--$idref_lang_part = xquery40- --></nt>  (("intersect"  |  "except")  <nt def="prod-xquery40-InstanceofExpr">InstanceofExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-ItemType">
                     <lhs>ItemType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-RegularItemType">RegularItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionType">FunctionType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ChoiceItemType">ChoiceItemType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ItemTypeDecl">
                     <lhs>ItemTypeDecl</lhs>
                     <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "type"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "as"  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-JNodeType">
                     <lhs>JNodeType</lhs>
                     <rhs>"jnode"  "("  (("*"  |  <nt def="prod-xquery40-JRootSelector">JRootSelector<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Constant">Constant<!--$idref_lang_part = xquery40- --></nt>)  (","  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?)?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-JRootSelector">
                     <lhs>JRootSelector</lhs>
                     <rhs>"("  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-KeySpecifier">
                     <lhs>KeySpecifier</lhs>
                     <rhs>
                        <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Literal">Literal<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ContextValueRef">ContextValueRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupWildcard">LookupWildcard<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-KeywordArgument">
                     <lhs>KeywordArgument</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  ":="  <nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-KeywordArguments">
                     <lhs>KeywordArguments</lhs>
                     <rhs>(<nt def="prod-xquery40-KeywordArgument">KeywordArgument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-LetArrayBinding">
                     <lhs>LetArrayBinding</lhs>
                     <rhs>"$"  "["  (<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ++ ",")  "]"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-LetBinding">
                     <lhs>LetBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-LetValueBinding">LetValueBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetSequenceBinding">LetSequenceBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetArrayBinding">LetArrayBinding<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LetMapBinding">LetMapBinding<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-LetClause">
                     <lhs>LetClause</lhs>
                     <rhs>"let"  (<nt def="prod-xquery40-LetBinding">LetBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-LetMapBinding">
                     <lhs>LetMapBinding</lhs>
                     <rhs>"$"  "{"  (<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ++ ",")  "}"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-LetSequenceBinding">
                     <lhs>LetSequenceBinding</lhs>
                     <rhs>"$"  "("  (<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ++ ",")  ")"  <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-LetValueBinding">
                     <lhs>LetValueBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  ":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-LibraryModule">
                     <lhs>LibraryModule</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ModuleDecl">ModuleDecl<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-Prolog">Prolog<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Literal">
                     <lhs>Literal</lhs>
                     <rhs>
                        <nt def="prod-xquery40-NumericLiteral">NumericLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QNameLiteral">QNameLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Lookup">
                     <lhs>Lookup</lhs>
                     <rhs>"?"  <nt def="prod-xquery40-KeySpecifier">KeySpecifier<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-LookupExpr">
                     <lhs>LookupExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-Lookup">Lookup<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-LookupWildcard">
                     <lhs>LookupWildcard</lhs>
                     <rhs>"*"</rhs>
                  </prod>

                  <prod id="prod-xquery40-MainModule">
                     <lhs>MainModule</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Prolog">Prolog<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-QueryBody">QueryBody<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-MapConstructor">
                     <lhs>MapConstructor</lhs>
                     <rhs>"map"?  "{"  (<nt def="prod-xquery40-MapConstructorEntry">MapConstructorEntry<!--$idref_lang_part = xquery40- --></nt> ** ",")  "}"</rhs>
                  </prod>

                  <prod id="prod-xquery40-MapConstructorEntry">
                     <lhs>MapConstructorEntry</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  (":"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-MappingArrowTarget">
                     <lhs>MappingArrowTarget</lhs>
                     <rhs>"=!&gt;"  <nt def="prod-xquery40-ArrowTarget">ArrowTarget<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-MapType">
                     <lhs>MapType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AnyMapType">AnyMapType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-TypedMapType">TypedMapType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-MarkedNCName">
                     <lhs>MarkedNCName</lhs>
                     <rhs>"#"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-MethodCall">
                     <lhs>MethodCall</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  "=?&gt;"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Module">
                     <lhs>Module</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VersionDecl">VersionDecl<!--$idref_lang_part = xquery40- --></nt>?  (<nt def="prod-xquery40-LibraryModule">LibraryModule<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MainModule">MainModule<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-ModuleDecl">
                     <lhs>ModuleDecl</lhs>
                     <rhs>"module"  "namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ModuleImport">
                     <lhs>ModuleImport</lhs>
                     <rhs>"import"  "module"  ("namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "=")?  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>  ("at"  (<nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt> ++ ","))?</rhs>
                  </prod>

                  <prod id="prod-xquery40-MultiplicativeExpr">
                     <lhs>MultiplicativeExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-UnionExpr">UnionExpr<!--$idref_lang_part = xquery40- --></nt>  (("*"  |  "×"  |  "div"  |  "÷"  |  "idiv"  |  "mod")  <nt def="prod-xquery40-UnionExpr">UnionExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-NamedFunctionRef">
                     <lhs>NamedFunctionRef</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "#"  <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-reserved-function-names">xgc: reserved-function-names</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-NamedRecordTypeDecl">
                     <lhs>NamedRecordTypeDecl</lhs>
                     <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "record"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "("  (<nt def="prod-xquery40-ExtendedFieldDeclaration">ExtendedFieldDeclaration<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-NamespaceDecl">
                     <lhs>NamespaceDecl</lhs>
                     <rhs>"declare"  "namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "="  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-NamespaceNodeType">
                     <lhs>NamespaceNodeType</lhs>
                     <rhs>"namespace-node"  "("  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-NameTest">
                     <lhs>NameTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-NameTestUnion">
                     <lhs>NameTestUnion</lhs>
                     <rhs>(<nt def="prod-xquery40-NameTest">NameTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")</rhs>
                  </prod>

                  <prod id="prod-xquery40-NextVar">
                     <lhs>NextVar</lhs>
                     <rhs>"next"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-NodeComp">
                     <lhs>NodeComp</lhs>
                     <rhs>"is"  |  "is-not"  |  <nt def="prod-xquery40-NodePrecedes">NodePrecedes<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NodeFollows">NodeFollows<!--$idref_lang_part = xquery40- --></nt>  |  "precedes-or-is"  |  "follows-or-is"</rhs>
                  </prod>

                  <prod id="prod-xquery40-NodeConstructor">
                     <lhs>NodeConstructor</lhs>
                     <rhs>
                        <nt def="prod-xquery40-DirectConstructor">DirectConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-ComputedConstructor">ComputedConstructor<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-NodeFollows">
                     <lhs>NodeFollows</lhs>
                     <rhs>"&gt;&gt;"  |  "follows"</rhs>
                  </prod>

                  <prod id="prod-xquery40-NodePrecedes">
                     <lhs>NodePrecedes</lhs>
                     <rhs>"&lt;&lt;"  |  "precedes"</rhs>
                  </prod>

                  <prod id="prod-xquery40-NodeTest">
                     <lhs>NodeTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-UnionNodeTest">UnionNodeTest<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-NumericLiteral">
                     <lhs>NumericLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BinaryIntegerLiteral">BinaryIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DecimalLiteral">DecimalLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DoubleLiteral">DoubleLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-OccurrenceIndicator">
                     <lhs>OccurrenceIndicator</lhs>
                     <rhs>"?"  |  "*"  |  "+"</rhs>
                     <com>
                        <loc href="#parse-note-occurrence-indicators">xgc: occurrence-indicators</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-OptionDecl">
                     <lhs>OptionDecl</lhs>
                     <rhs>"declare"  "option"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-OrderByClause">
                     <lhs>OrderByClause</lhs>
                     <rhs>"stable"?  "order"  "by"  (<nt def="prod-xquery40-OrderSpec">OrderSpec<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-OrderedExpr">
                     <lhs>OrderedExpr</lhs>
                     <rhs>"ordered"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-OrderingModeDecl">
                     <lhs>OrderingModeDecl</lhs>
                     <rhs>"declare"  "ordering"  ("ordered"  |  "unordered")</rhs>
                  </prod>

                  <prod id="prod-xquery40-OrderModifier">
                     <lhs>OrderModifier</lhs>
                     <rhs>("ascending"  |  "descending")?  ("empty"  ("greatest"  |  "least"))?  ("collation"  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-OrderSpec">
                     <lhs>OrderSpec</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OrderModifier">OrderModifier<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-OrExpr">
                     <lhs>OrExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AndExpr">AndExpr<!--$idref_lang_part = xquery40- --></nt>  ("or"  <nt def="prod-xquery40-AndExpr">AndExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-OtherwiseExpr">
                     <lhs>OtherwiseExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-StringConcatExpr">StringConcatExpr<!--$idref_lang_part = xquery40- --></nt>  ("otherwise"  <nt def="prod-xquery40-StringConcatExpr">StringConcatExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-ParamList">
                     <lhs>ParamList</lhs>
                     <rhs>(<nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt> ** ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-ParamListWithDefaults">
                     <lhs>ParamListWithDefaults</lhs>
                     <rhs>(<nt def="prod-xquery40-ParamWithDefault">ParamWithDefault<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-ParamWithDefault">
                     <lhs>ParamWithDefault</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  (":="  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-ParenthesizedExpr">
                     <lhs>ParenthesizedExpr</lhs>
                     <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-PathExpr">
                     <lhs>PathExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AbsolutePathExpr">AbsolutePathExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-RelativePathExpr">RelativePathExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-leading-lone-slash">xgc: leading-lone-slash</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-PipelineExpr">
                     <lhs>PipelineExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ArrowExpr">ArrowExpr<!--$idref_lang_part = xquery40- --></nt>  ("-&gt;"  <nt def="prod-xquery40-ArrowExpr">ArrowExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-PositionalArgumentList">
                     <lhs>PositionalArgumentList</lhs>
                     <rhs>"("  <nt def="prod-xquery40-PositionalArguments">PositionalArguments<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-PositionalArguments">
                     <lhs>PositionalArguments</lhs>
                     <rhs>(<nt def="prod-xquery40-Argument">Argument<!--$idref_lang_part = xquery40- --></nt> ++ ",")</rhs>
                  </prod>

                  <prod id="prod-xquery40-PositionalVar">
                     <lhs>PositionalVar</lhs>
                     <rhs>"at"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-PostfixExpr">
                     <lhs>PostfixExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PrimaryExpr">PrimaryExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExpr">FilterExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DynamicFunctionCall">DynamicFunctionCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-LookupExpr">LookupExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MethodCall">MethodCall<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FilterExprAM">FilterExprAM<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Pragma">
                     <lhs>Pragma</lhs>
                     <rhs>"(#"  <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-PragmaContents">PragmaContents<!--$idref_lang_part = xquery40- --></nt>)?  "#)"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-PragmaContents">
                     <lhs>PragmaContents</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* '#)' Char*))</rhs>
                  </prod>

                  <prod id="prod-xquery40-Predicate">
                     <lhs>Predicate</lhs>
                     <rhs>"["  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "]"</rhs>
                  </prod>

                  <prod id="prod-xquery40-PreserveMode">
                     <lhs>PreserveMode</lhs>
                     <rhs>"preserve"  |  "no-preserve"</rhs>
                  </prod>

                  <prod id="prod-xquery40-PreviousVar">
                     <lhs>PreviousVar</lhs>
                     <rhs>"previous"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-PrimaryExpr">
                     <lhs>PrimaryExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Literal">Literal<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-ContextValueRef">ContextValueRef<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-FunctionCall">FunctionCall<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-OrderedExpr">OrderedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-UnorderedExpr">UnorderedExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-NodeConstructor">NodeConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-FunctionItemExpr">FunctionItemExpr<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-MapConstructor">MapConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-ArrayConstructor">ArrayConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-StringTemplate">StringTemplate<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-StringConstructor">StringConstructor<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-UnaryLookup">UnaryLookup<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ProcessingInstructionNodeType">
                     <lhs>ProcessingInstructionNodeType</lhs>
                     <rhs>"processing-instruction"  "("  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-Prolog">
                     <lhs>Prolog</lhs>
                     <rhs>((<nt def="prod-xquery40-DefaultNamespaceDecl">DefaultNamespaceDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Setter">Setter<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NamespaceDecl">NamespaceDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Import">Import<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>)*  ((<nt def="prod-xquery40-ContextValueDecl">ContextValueDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-VarDecl">VarDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionDecl">FunctionDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ItemTypeDecl">ItemTypeDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-NamedRecordTypeDecl">NamedRecordTypeDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-OptionDecl">OptionDecl<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-QNameLiteral">
                     <lhs>QNameLiteral</lhs>
                     <rhs>"#"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-QuantifiedExpr">
                     <lhs>QuantifiedExpr</lhs>
                     <rhs>("some"  |  "every")  (<nt def="prod-xquery40-QuantifierBinding">QuantifierBinding<!--$idref_lang_part = xquery40- --></nt> ++ ",")  "satisfies"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-QuantifierBinding">
                     <lhs>QuantifierBinding</lhs>
                     <rhs>
                        <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-QueryBody">
                     <lhs>QueryBody</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-QuotAttrValueContent">
                     <lhs>QuotAttrValueContent</lhs>
                     <rhs>
                        <nt def="prod-xquery40-QuotAttrContentChar">QuotAttrContentChar<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CommonContent">CommonContent<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-RangeExpr">
                     <lhs>RangeExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>  ("to"  <nt def="prod-xquery40-AdditiveExpr">AdditiveExpr<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-RecordType">
                     <lhs>RecordType</lhs>
                     <rhs>"record"  "("  (<nt def="prod-xquery40-FieldDeclaration">FieldDeclaration<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-RegularItemType">
                     <lhs>RegularItemType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AnyItemType">AnyItemType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-XNodeType">XNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-GNodeType">GNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-JNodeType">JNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MapType">MapType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArrayType">ArrayType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-RecordType">RecordType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EnumerationType">EnumerationType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-RelativePathExpr">
                     <lhs>RelativePathExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-StepExpr">StepExpr<!--$idref_lang_part = xquery40- --></nt>  (("/"  |  "//")  <nt def="prod-xquery40-StepExpr">StepExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-RestrictedDynamicCall">
                     <lhs>RestrictedDynamicCall</lhs>
                     <rhs>(<nt def="prod-xquery40-VarRef">VarRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ParenthesizedExpr">ParenthesizedExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-FunctionItemExpr">FunctionItemExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-MapConstructor">MapConstructor<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ArrayConstructor">ArrayConstructor<!--$idref_lang_part = xquery40- --></nt>)  <nt def="prod-xquery40-PositionalArgumentList">PositionalArgumentList<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ReturnClause">
                     <lhs>ReturnClause</lhs>
                     <rhs>"return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SchemaAttributeNodeType">
                     <lhs>SchemaAttributeNodeType</lhs>
                     <rhs>"schema-attribute"  "("  <nt def="prod-xquery40-AttributeName">AttributeName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-SchemaElementNodeType">
                     <lhs>SchemaElementNodeType</lhs>
                     <rhs>"schema-element"  "("  <nt def="prod-xquery40-ElementName">ElementName<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-SchemaImport">
                     <lhs>SchemaImport</lhs>
                     <rhs>"import"  "schema"  <nt def="prod-xquery40-SchemaPrefix">SchemaPrefix<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt>  ("at"  (<nt def="prod-xquery40-URILiteral">URILiteral<!--$idref_lang_part = xquery40- --></nt> ++ ","))?</rhs>
                  </prod>

                  <prod id="prod-xquery40-SchemaPrefix">
                     <lhs>SchemaPrefix</lhs>
                     <rhs>("namespace"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  "=")  |  ("fixed"?  "default"  "element"  "namespace")</rhs>
                  </prod>

                  <prod id="prod-xquery40-Selector">
                     <lhs>Selector</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Wildcard">Wildcard<!--$idref_lang_part = xquery40- --></nt>  |  ("get"  "("  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  ")")</rhs>
                  </prod>

                  <prod id="prod-xquery40-Separator">
                     <lhs>Separator</lhs>
                     <rhs>";"</rhs>
                  </prod>

                  <prod id="prod-xquery40-SequenceArrowTarget">
                     <lhs>SequenceArrowTarget</lhs>
                     <rhs>"=&gt;"  <nt def="prod-xquery40-ArrowTarget">ArrowTarget<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SequenceType">
                     <lhs>SequenceType</lhs>
                     <rhs>("empty-sequence"  "("  ")")<br/>|  (<nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                  </prod>

                  <prod id="prod-xquery40-SequenceTypeUnion">
                     <lhs>SequenceTypeUnion</lhs>
                     <rhs>
                        <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>  ("|"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-Setter">
                     <lhs>Setter</lhs>
                     <rhs>
                        <nt def="prod-xquery40-BoundarySpaceDecl">BoundarySpaceDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DefaultCollationDecl">DefaultCollationDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BaseURIDecl">BaseURIDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ConstructionDecl">ConstructionDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-OrderingModeDecl">OrderingModeDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EmptyOrderDecl">EmptyOrderDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CopyNamespacesDecl">CopyNamespacesDecl<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-DecimalFormatDecl">DecimalFormatDecl<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SimpleMapExpr">
                     <lhs>SimpleMapExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PathExpr">PathExpr<!--$idref_lang_part = xquery40- --></nt>  ("!"  <nt def="prod-xquery40-PathExpr">PathExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-SimpleNodeTest">
                     <lhs>SimpleNodeTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TypeTest">TypeTest<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Selector">Selector<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SlidingWindowClause">
                     <lhs>SlidingWindowClause</lhs>
                     <rhs>"sliding"  "window"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SquareArrayConstructor">
                     <lhs>SquareArrayConstructor</lhs>
                     <rhs>"["  (<nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt> ** ",")  "]"</rhs>
                  </prod>

                  <prod id="prod-xquery40-StepExpr">
                     <lhs>StepExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-PostfixExpr">PostfixExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-AxisStep">AxisStep<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-StringConcatExpr">
                     <lhs>StringConcatExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-RangeExpr">RangeExpr<!--$idref_lang_part = xquery40- --></nt>  ("||"  <nt def="prod-xquery40-RangeExpr">RangeExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-StringConstructor">
                     <lhs>StringConstructor</lhs>
                     <rhs>"``["  <nt def="prod-xquery40-StringConstructorContent">StringConstructorContent<!--$idref_lang_part = xquery40- --></nt>  "]``"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-StringConstructorChars">
                     <lhs>StringConstructorChars</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>* - (Char* ('`{' | ']``') Char*))</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-StringConstructorContent">
                     <lhs>StringConstructorContent</lhs>
                     <rhs>
                        <nt def="prod-xquery40-StringConstructorChars">StringConstructorChars<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-StringInterpolation">StringInterpolation<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-StringConstructorChars">StringConstructorChars<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-StringInterpolation">
                     <lhs>StringInterpolation</lhs>
                     <rhs>"`{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  "}`"</rhs>
                  </prod>

                  <prod id="prod-xquery40-StringTemplate">
                     <lhs>StringTemplate</lhs>
                     <rhs>"`"  (<nt def="prod-xquery40-StringTemplateFixedPart">StringTemplateFixedPart<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-StringTemplateVariablePart">StringTemplateVariablePart<!--$idref_lang_part = xquery40- --></nt>)*  "`"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-StringTemplateFixedPart">
                     <lhs>StringTemplateFixedPart</lhs>
                     <rhs>((<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - ('{' | '}' | '`'))  |  "{{"  |  "}}"  |  "``")+</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-StringTemplateVariablePart">
                     <lhs>StringTemplateVariablePart</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SwitchCaseClause">
                     <lhs>SwitchCaseClause</lhs>
                     <rhs>("case"  <nt def="prod-xquery40-SwitchCaseOperand">SwitchCaseOperand<!--$idref_lang_part = xquery40- --></nt>)+  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SwitchCaseOperand">
                     <lhs>SwitchCaseOperand</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SwitchCases">
                     <lhs>SwitchCases</lhs>
                     <rhs>
                        <nt def="prod-xquery40-SwitchCaseClause">SwitchCaseClause<!--$idref_lang_part = xquery40- --></nt>+  "default"  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-SwitchComparand">
                     <lhs>SwitchComparand</lhs>
                     <rhs>"("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>?  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-SwitchExpr">
                     <lhs>SwitchExpr</lhs>
                     <rhs>"switch"  <nt def="prod-xquery40-SwitchComparand">SwitchComparand<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-SwitchCases">SwitchCases<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedSwitchCases">BracedSwitchCases<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-TextNodeType">
                     <lhs>TextNodeType</lhs>
                     <rhs>"text"  "("  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-TreatExpr">
                     <lhs>TreatExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CastableExpr">CastableExpr<!--$idref_lang_part = xquery40- --></nt>  ("treat"  "as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-TryCatchExpr">
                     <lhs>TryCatchExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-TryClause">TryClause<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-CatchClause">CatchClause<!--$idref_lang_part = xquery40- --></nt>+  <nt def="prod-xquery40-FinallyClause">FinallyClause<!--$idref_lang_part = xquery40- --></nt>?)  |  <nt def="prod-xquery40-FinallyClause">FinallyClause<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-TryClause">
                     <lhs>TryClause</lhs>
                     <rhs>"try"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-TumblingWindowClause">
                     <lhs>TumblingWindowClause</lhs>
                     <rhs>"tumbling"  "window"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  "in"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-WindowStartCondition">WindowStartCondition<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-WindowEndCondition">WindowEndCondition<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="prod-xquery40-TypedArrayType">
                     <lhs>TypedArrayType</lhs>
                     <rhs>"array"  "("  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-TypeDeclaration">
                     <lhs>TypeDeclaration</lhs>
                     <rhs>"as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-TypedFunctionParam">
                     <lhs>TypedFunctionParam</lhs>
                     <rhs>("$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>  "as")?  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-TypedFunctionType">
                     <lhs>TypedFunctionType</lhs>
                     <rhs>("function"  |  "fn")  "("  (<nt def="prod-xquery40-TypedFunctionParam">TypedFunctionParam<!--$idref_lang_part = xquery40- --></nt> ** ",")  ")"  "as"  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-TypedMapType">
                     <lhs>TypedMapType</lhs>
                     <rhs>"map"  "("  <nt def="prod-xquery40-ItemType">ItemType<!--$idref_lang_part = xquery40- --></nt>  ","  <nt def="prod-xquery40-SequenceType">SequenceType<!--$idref_lang_part = xquery40- --></nt>  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-TypeName">
                     <lhs>TypeName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-TypeswitchCases">
                     <lhs>TypeswitchCases</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CaseClause">CaseClause<!--$idref_lang_part = xquery40- --></nt>+  "default"  <nt def="prod-xquery40-VarName">VarName<!--$idref_lang_part = xquery40- --></nt>?  "return"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-TypeswitchExpr">
                     <lhs>TypeswitchExpr</lhs>
                     <rhs>"typeswitch"  "("  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  ")"  (<nt def="prod-xquery40-TypeswitchCases">TypeswitchCases<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-BracedTypeswitchCases">BracedTypeswitchCases<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-TypeTest">
                     <lhs>TypeTest</lhs>
                     <rhs>
                        <nt def="prod-xquery40-GNodeType">GNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-XNodeType">XNodeType<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-JNodeType">JNodeType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-UnaryExpr">
                     <lhs>UnaryExpr</lhs>
                     <rhs>("-"  |  "+")*  <nt def="prod-xquery40-ValueExpr">ValueExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-UnaryLookup">
                     <lhs>UnaryLookup</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Lookup">Lookup<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-UnbracedActions">
                     <lhs>UnbracedActions</lhs>
                     <rhs>"then"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>  "else"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-UnionExpr">
                     <lhs>UnionExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-IntersectExceptExpr">IntersectExceptExpr<!--$idref_lang_part = xquery40- --></nt>  (("union"  |  "|")  <nt def="prod-xquery40-IntersectExceptExpr">IntersectExceptExpr<!--$idref_lang_part = xquery40- --></nt>)*</rhs>
                  </prod>

                  <prod id="prod-xquery40-UnionNodeTest">
                     <lhs>UnionNodeTest</lhs>
                     <rhs>"("  (<nt def="prod-xquery40-SimpleNodeTest">SimpleNodeTest<!--$idref_lang_part = xquery40- --></nt> ++ "|")  ")"</rhs>
                  </prod>

                  <prod id="prod-xquery40-UnorderedExpr">
                     <lhs>UnorderedExpr</lhs>
                     <rhs>"unordered"  <nt def="prod-xquery40-EnclosedExpr">EnclosedExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-UnreservedName">
                     <lhs>UnreservedName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-unreserved-name">xgc: unreserved-name</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-UnreservedNCName">
                     <lhs>UnreservedNCName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-unreserved-name">xgc: unreserved-name</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-URILiteral">
                     <lhs>URILiteral</lhs>
                     <rhs>
                        <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-ValidateExpr">
                     <lhs>ValidateExpr</lhs>
                     <rhs>"validate"  (<nt def="prod-xquery40-ValidationMode">ValidationMode<!--$idref_lang_part = xquery40- --></nt>  |  ("type"  <nt def="prod-xquery40-TypeName">TypeName<!--$idref_lang_part = xquery40- --></nt>))?  "{"  <nt def="prod-xquery40-Expr">Expr<!--$idref_lang_part = xquery40- --></nt>  "}"</rhs>
                  </prod>

                  <prod id="prod-xquery40-ValidationMode">
                     <lhs>ValidationMode</lhs>
                     <rhs>"lax"  |  "strict"</rhs>
                  </prod>

                  <prod id="prod-xquery40-ValueComp">
                     <lhs>ValueComp</lhs>
                     <rhs>"eq"  |  "ne"  |  "lt"  |  "le"  |  "gt"  |  "ge"</rhs>
                  </prod>

                  <prod id="prod-xquery40-ValueExpr">
                     <lhs>ValueExpr</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ValidateExpr">ValidateExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-ExtensionExpr">ExtensionExpr<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SimpleMapExpr">SimpleMapExpr<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-VarDecl">
                     <lhs>VarDecl</lhs>
                     <rhs>"declare"  <nt def="prod-xquery40-Annotation">Annotation<!--$idref_lang_part = xquery40- --></nt>*  "variable"  <nt def="prod-xquery40-VarNameAndType">VarNameAndType<!--$idref_lang_part = xquery40- --></nt>  ((":="  <nt def="prod-xquery40-VarValue">VarValue<!--$idref_lang_part = xquery40- --></nt>)  |  ("external"  (":="  <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$idref_lang_part = xquery40- --></nt>)?))</rhs>
                  </prod>

                  <prod id="prod-xquery40-VarDefaultValue">
                     <lhs>VarDefaultValue</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-VarName">
                     <lhs>VarName</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-VarNameAndType">
                     <lhs>VarNameAndType</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                        <nt def="prod-xquery40-TypeDeclaration">TypeDeclaration<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="prod-xquery40-VarRef">
                     <lhs>VarRef</lhs>
                     <rhs>"$"  <nt def="prod-xquery40-EQName">EQName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-VarValue">
                     <lhs>VarValue</lhs>
                     <rhs>
                        <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-VersionDecl">
                     <lhs>VersionDecl</lhs>
                     <rhs>"xquery"  (("encoding"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)  |  ("version"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>  ("encoding"  <nt def="doc-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>)?))  <nt def="prod-xquery40-Separator">Separator<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-WhereClause">
                     <lhs>WhereClause</lhs>
                     <rhs>"where"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-WhileClause">
                     <lhs>WhileClause</lhs>
                     <rhs>"while"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>

                  <prod id="prod-xquery40-Wildcard">
                     <lhs>Wildcard</lhs>
                     <rhs>"*"<br/>|  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":*")<br/>|  ("*:"  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>)<br/>|  (<nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  "*")</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-WindowClause">
                     <lhs>WindowClause</lhs>
                     <rhs>"for"  (<nt def="prod-xquery40-TumblingWindowClause">TumblingWindowClause<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-SlidingWindowClause">SlidingWindowClause<!--$idref_lang_part = xquery40- --></nt>)</rhs>
                  </prod>

                  <prod id="prod-xquery40-WindowEndCondition">
                     <lhs>WindowEndCondition</lhs>
                     <rhs>"only"?  "end"  <nt def="prod-xquery40-WindowVars">WindowVars<!--$idref_lang_part = xquery40- --></nt>  ("when"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-WindowStartCondition">
                     <lhs>WindowStartCondition</lhs>
                     <rhs>"start"  <nt def="prod-xquery40-WindowVars">WindowVars<!--$idref_lang_part = xquery40- --></nt>  ("when"  <nt def="prod-xquery40-ExprSingle">ExprSingle<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                  </prod>

                  <prod id="prod-xquery40-WindowVars">
                     <lhs>WindowVars</lhs>
                     <rhs>
                        <nt def="prod-xquery40-CurrentVar">CurrentVar<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-PositionalVar">PositionalVar<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-PreviousVar">PreviousVar<!--$idref_lang_part = xquery40- --></nt>?  <nt def="prod-xquery40-NextVar">NextVar<!--$idref_lang_part = xquery40- --></nt>?</rhs>
                  </prod>

                  <prod id="prod-xquery40-XNodeType">
                     <lhs>XNodeType</lhs>
                     <rhs>
                        <nt def="prod-xquery40-DocumentNodeType">DocumentNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-ElementNodeType">ElementNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="doc-xquery40-AttributeNodeType">AttributeNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SchemaElementNodeType">SchemaElementNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-SchemaAttributeNodeType">SchemaAttributeNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-ProcessingInstructionNodeType">ProcessingInstructionNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-CommentNodeType">CommentNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-TextNodeType">TextNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-NamespaceNodeType">NamespaceNodeType<!--$idref_lang_part = xquery40- --></nt>
                        <br/>|  <nt def="prod-xquery40-AnyXNodeType">AnyXNodeType<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                  </prod>
               </prodgroup>
            </scrap>
            <div3 id="EBNFNotation">
               <head>Notation</head>
               <changes>
                  <change issue="1366" PR="1498">The EBNF operators <code nobreak="false">++</code> and <code nobreak="false">**</code>
        have been introduced, for more concise representation of sequences using a character
        such as <code nobreak="false">","</code> as a separator. The notation is borrowed from Invisible XML.</change>
               </changes>
               <p>
                  <termdef id="symbol" term="symbol">Each rule in the grammar defines one <term>symbol</term>,
          using the following format: <eg xml:space="preserve">symbol ::= expression</eg>
                  </termdef>
               </p>
               <p>
                  <termdef term="terminal" id="terminal">A <term>terminal</term> is a symbol or string or
          pattern that can appear in the right-hand side of a rule, but never appears on the
          left-hand side in the main grammar, although it may appear on the left-hand side of a rule
          in the grammar for terminals.</termdef> The following constructs are used to match strings
        of one or more characters in a terminal:</p>
               <glist>
                  <gitem>
                     <label>[a-zA-Z]</label>
                     <def>
                        <p>matches any <nt def="prod-xquery40-Char">Char<!--$spec = xquery40--></nt> with a value in the range(s) indicated
              (inclusive).</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>[abc]</label>
                     <def>
                        <p>matches any <nt def="prod-xquery40-Char">Char<!--$spec = xquery40--></nt> with a value among the characters enumerated.
            </p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>[^abc]</label>
                     <def>
                        <p>matches any <nt def="prod-xquery40-Char">Char<!--$spec = xquery40--></nt> with a value not among the characters given.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>"string" or 'string'</label>
                     <def>
                        <p>matches the sequence of characters that appear inside the double or single quotation marks.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label> [http://www.w3.org/TR/REC-example/#NT-Example]</label>
                     <def>
                        <p>matches any string matched by the production defined in the external specification as
              per the provided reference.</p>
                     </def>
                  </gitem>
               </glist>
               <p>Patterns (including the above constructs) can be combined with grammatical operators to
        form more complex patterns, matching more complex sets of character strings. In the examples
        that follow, <var>A</var> and <var>B</var> represent (sub-)patterns.</p>
               <glist>
                  <gitem>
                     <label>(A)</label>
                     <def>
                        <p>
                           <code nobreak="false">A</code> is treated as a unit and may be combined as described in this list.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>A?</label>
                     <def>
                        <p>matches <code nobreak="false">A</code> or nothing; optional <code nobreak="false">A</code>.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>A B</label>
                     <def>
                        <p>matches <code nobreak="false">A</code> followed by <code nobreak="false">B</code>. This implicit operator has higher
              precedence than the choice operator <code nobreak="false">|</code>; thus <code nobreak="false">A B | C D</code> is 
              interpreted as <code nobreak="false">(A B) | (C D)</code>.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>A | B</label>
                     <def>
                        <p>matches <code nobreak="false">A</code> or <code nobreak="false">B</code> but not both.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>A - B</label>
                     <def>
                        <p>matches any string that matches <code nobreak="false">A</code> but does not match <code nobreak="false">B</code>.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>A+</label>
                     <def>
                        <p>matches one or more occurrences of <code nobreak="false">A</code>. Concatenation has higher
              precedence than choice; thus <code nobreak="false">A+ | B+</code> is identical to <code nobreak="false">(A+) |
                (B+)</code>.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>A*</label>
                     <def>
                        <p>matches zero or more occurrences of <code nobreak="false">A</code>. Concatenation has higher
              precedence than choice; thus <code nobreak="false">A* | B*</code> is identical to <code nobreak="false">(A*) |
                (B*)</code>
                        </p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>(A ++ B)</label>
                     <def>
                        <p>matches one or more occurrences of <code nobreak="false">A</code>, with one occurrence of <code nobreak="false">B</code>
              between adjacent occurrences of <code nobreak="false">A</code>. 
              The notation <code nobreak="false">A ++ B</code> is a shorthand for <code nobreak="false">A (B A)*</code>. The construct
              is always parenthesized to avoid ambiguity, and although in principle
              <code nobreak="false">B</code> could be any pattern, in practice the notation is used only when it is a simple string literal
              (typically but not invariably <code nobreak="false">","</code>).</p>
                        <p>For example, <code nobreak="false">(Digit ++ ".")</code> matches <code nobreak="false">1</code> or <code nobreak="false">1.2</code>
            or <code nobreak="false">1.2.3</code>.</p>
                     </def>
                  </gitem>
                  <gitem>
                     <label>(A ** B)</label>
                     <def>
                        <p>matches zero or more occurrences of <code nobreak="false">A</code>, with one occurrence of <code nobreak="false">B</code>
              between adjacent occurrences of <code nobreak="false">A</code>.  
              The notation <code nobreak="false">A ** B</code> is a shorthand for <code nobreak="false">(A (B A)*)?</code>. The construct
              is always parenthesized to avoid ambiguity, and although in principle
              <code nobreak="false">B</code> could be any pattern, in practice the notation is used only when it is a simple string literal
              (typically but not invariably <code nobreak="false">","</code>).</p>
                        <p>For example, <code nobreak="false">"[" (Digit ** "|") "]"</code> matches <code nobreak="false">[]</code> or <code nobreak="false">[1]</code> or <code nobreak="false">[1|2]</code>
            or <code nobreak="false">[1|2|3]</code>.</p>
                     </def>
                  </gitem>
               </glist>
            </div3>
            <div3 id="extra-grammatical-constraints">
               <head>Extra-grammatical Constraints</head>
               <p>This section contains constraints on the EBNF productions, which are required to parse
        syntactically valid sentences. The notes below are referenced from the right side of the
        production, with the notation: <emph>/* xgc: &lt;id&gt; */</emph>.</p>
               <constraintnote id="parse-note-leading-lone-slash" type="xgc">
                  <head>leading-lone-slash</head>
                  <p>A single slash may appear either as a complete path expression or as the first part of a
          path expression in which it is followed by a <nt def="doc-xquery40-RelativePathExpr">RelativePathExpr<!--$spec = xquery40--></nt>. In some cases, the next terminal after the slash is insufficient to
          allow a parser to distinguish these two possibilities: a <code nobreak="false">*</code> symbol or a
          keyword like <code nobreak="false">union</code> could be either an operator or a <nt def="prod-xquery40-NameTest">NameTest<!--$spec = xquery40--></nt>. For example, the expression <code nobreak="false">/union/*</code> could be parsed
          either as <code nobreak="false">(/) union (/*)</code> or as <code nobreak="false">/child::union/child::*</code> (the
          second interpretation is the one chosen).</p>
                  <p>The situation where <code nobreak="false">/</code> is followed by <code nobreak="false">&lt;</code> is a little more
          complicated. In XPath, this is unambiguous: the <code nobreak="false">&lt;</code> can only indicate
          one of the operators <code nobreak="false">&lt;</code>, <code nobreak="false">&lt;=</code>, or <code nobreak="false">&lt;&lt;</code>.
          In XQuery, however, it can also be the start of a direct constructor: specifically,
          a direct constructor for an element node, processing instruction node, or comment node.
          These constructs are identified by the tokenizer, independently of their syntactic
          context, as described in <specref ref="lexical-structure"/>.</p>
                  <p>The rule adopted is as follows: if the terminal immediately following a slash
          can form the start of a <nt def="doc-xquery40-RelativePathExpr">RelativePathExpr<!--$spec = xquery40--></nt>, then the slash
          must be the beginning of a <nt def="doc-xquery40-PathExpr">PathExpr<!--$spec = xquery40--></nt>, not the entirety of it.</p>
                  <p>The terminals that can form the start of a <nt def="doc-xquery40-RelativePathExpr">RelativePathExpr<!--$spec = xquery40--></nt>
        are: <code nobreak="false">NCName</code>, <code nobreak="false">QName</code>, <code nobreak="false">URIQualifiedName</code>,
          <code nobreak="false">StringLiteral</code>, <code nobreak="false">NumericLiteral</code>, 
          <code nobreak="false">Wildcard</code>, and <code nobreak="false">StringTemplate</code>; 
        plus <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>
                     <code nobreak="false">%</code>
                     <code nobreak="false">(</code>
                     <code nobreak="false">[</code>; and in XQuery <code nobreak="false">StringConstructor</code> and <code nobreak="false">DirectConstructor</code>.
        </p>
                  <!-- The above list was obtained by running the stylesheet leading-tokens.xsl against xpath-grammar.xml -->
                  <p>A single slash may be used as the left-hand argument of an operator by parenthesizing it:
            <code role="parse-test" nobreak="false">(/) * 5</code>. The expression <code role="parse-test" nobreak="false">5 *
            /</code>, on the other hand, is syntactically valid without parentheses.</p>
               </constraintnote>
               <constraintnote id="parse-note-unreserved-name" type="xgc" role="xquery">
                  <head>unreserved-name</head>
                  <p>In a computed node constructor of the form
        <code nobreak="false">element <var>NNN</var> {}</code>, <code nobreak="false">attribute <var>NNN</var> {}</code>,
          <code nobreak="false">processing-instruction <var>NNN</var> {}</code>, or <code nobreak="false">namespace <var>NNN</var> {}</code>,
          XQuery 4.0 allows the name <var>NNN</var>
        to be written as a plain <code nobreak="false">NCName</code> only if it is not a reserved keyword: specifically, if it
        is not one of the following <termref def="dt-literal-terminal">literal terminals</termref>:</p>
                  <p>
                     <code nobreak="false">and</code>
                     <code nobreak="false">case</code>
                     <code nobreak="false">div</code>
                     <code nobreak="false">else</code>
                     <code nobreak="false">eq</code>
                     <code nobreak="false">except</code>
                     <code nobreak="false">follows</code>
                     <code nobreak="false">follows-or-is</code>
                     <code nobreak="false">for</code>
                     <code nobreak="false">ge</code>
                     <code nobreak="false">gt</code>
                     <code nobreak="false">idiv</code>
                     <code nobreak="false">intersect</code>
                     <code nobreak="false">is</code>
                     <code nobreak="false">is-not</code>
                     <code nobreak="false">le</code>
                     <code nobreak="false">let</code>
                     <code nobreak="false">lt</code>
                     <code nobreak="false">mod</code>
                     <code nobreak="false">ne</code>
                     <code nobreak="false">or</code>
                     <code nobreak="false">otherwise</code>
                     <code nobreak="false">precedes</code>
                     <code nobreak="false">precedes-or-is</code>
                     <code nobreak="false">return</code>
                     <code nobreak="false">satisfies</code>
                     <code nobreak="false">to</code>
                     <code nobreak="false">union</code>
                     <code nobreak="false">where</code>
                     <code nobreak="false">while</code>
                  </p>
                  <p>If such names (for example
        <code nobreak="false">div</code>) are to be used as node names in a computed
        node constructor, they must be preceded with a leading <code nobreak="false">#</code> character.</p>
                  <p>This rule is new in XQuery 4.0, and represents a backwards incompatibility. To ease transition, implementations
        may provide an option to allow such names to be accepted with a warning that the construct is deprecated.</p>
                  <note>
                     <p>The rule is introduced because the introduction of map constructors without the leading <code nobreak="false">map</code>
          keyword would otherwise cause expressions such as <code nobreak="false">element union {$map}</code> to become ambiguous.</p>
                     <p>The list of keywords that have become reserved includes (a) all binary operators spelled as NCNames
            (for example, <code nobreak="false">and</code>, <code nobreak="false">div</code>);
          (b) keywords that can appear at the start of a clause in a FLWOR expression, and that
          can be followed by a left curly brace (for example, <code nobreak="false">for</code>, <code nobreak="false">let</code>, <code nobreak="false">where</code>,
          <code nobreak="false">while</code>, <code nobreak="false">return</code>); and (c) a few other keywords (for example <code nobreak="false">case</code> and <code nobreak="false">else</code>)
          that can appear between two arbitrary expressions.</p>
                  </note>
                  <p>Users should be aware that future versions of XQuery may extend the list of reserved keywords. The safe policy
        is always to use a QName literal, for example <code nobreak="false">attribute #type {...}</code> rather than <code nobreak="false">attribute type {...}</code>,
        even though the keyword <code nobreak="false">type</code> is not currently reserved.</p>
               </constraintnote>
               <constraintnote id="parse-note-xml-version" type="xgc">
                  <head>xml-version</head>
                  <p>The version of XML and XML Names (e.g. <bibref ref="XML"/> and <bibref ref="XMLNAMES"/>,
          or <bibref ref="XML1.1"/> and <bibref ref="XMLNAMES11"/>) is <termref def="dt-implementation-defined">implementation-defined</termref>. It is recommended that
          the latest applicable version be used (even if it is published later than this
          specification). The EBNF in this specification links only to the 1.0 versions. Note also
          that these external productions follow the whitespace rules of their respective
          specifications, and not the rules of this specification, in particular <specref ref="DefaultWhitespaceHandling"/>. Thus <code nobreak="false">prefix : localname</code> is not a
          syntactically valid <termref def="dt-qname">lexical QName</termref> for purposes of this
          specification, just as it is not permitted in a XML document. Also, comments are not
          permissible on either side of the colon. Also extra-grammatical constraints such as
          well-formedness constraints must be taken into account.</p>
                  <p role="xquery">XML 1.0 and XML 1.1 differ in their handling of C0 control characters
          (specifically #x1 through #x1F, excluding #x9, #xA, and #xD) and C1 control characters
          (#x7F through #x9F). In XML 1.0, these C0 characters are prohibited, and the C1 characters
          are permitted. In XML 1.1, both sets of control characters are permitted, but only if
          written as character references. It is RECOMMENDED that implementations should follow the
          XML 1.1 rules in this respect; however, for backwards compatibility with <phrase role="xquery">XQuery 1.0</phrase>
          , implementations MAY allow C1 control characters
          to be used directly. <note>
                        <p>Direct use of C1 control characters often suggests a
              character encoding error, such as using encoding CP-1252 and mislabeling it as
              iso-8859-1.</p>
                     </note>
                  </p>
               </constraintnote>
               <constraintnote id="parse-note-reserved-function-names" type="xgc">
                  <head>reserved-function-names</head>
                  <p>Unprefixed function names spelled the same way as language keywords could make the
          language impossible to parse. For instance, <code nobreak="false">element(foo)</code> could be taken either as
          a <nt def="doc-xquery40-FunctionCall">FunctionCall<!--$spec = xquery40--></nt> or as an <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt>. 
          Therefore, an unprefixed function name must not be any of the names in
            <specref ref="id-reserved-fn-names"/>.</p>
                  <p>A function named <code nobreak="false">if</code> can be called by binding its namespace to a prefix and using the
          prefixed form: <code nobreak="false">library:if(foo)</code> instead of <code nobreak="false">if(foo)</code>.</p>
               </constraintnote>
               <constraintnote id="parse-note-occurrence-indicators" type="xgc">
                  <head>occurrence-indicators</head>
                  <p diff="chg" at="2023-05-22">As written, the grammar in <specref ref="nt-bnf"/> is ambiguous for some forms using the
          <code nobreak="false">"+"</code>, <code nobreak="false">"?"</code> and <code nobreak="false">"*"</code>
                     <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicators<!--$spec = xquery40--></nt>. 
          The ambiguity is resolved as follows: these operators are
          tightly bound to the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> expression, and have higher
          precedence than other uses of these symbols. Any occurrence of <code nobreak="false">"+"</code>, 
          <code nobreak="false">"?"</code> or <code nobreak="false">"*"</code>, that follows a sequence type is assumed to be an occurrence indicator, which binds to
          the last <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt> in the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt>.</p>
                  <p>Thus, <code role="parse-test" nobreak="false">4 treat as item() + - 5</code> must be interpreted as <code role="parse-test" nobreak="false">(4 treat as item()+) - 5</code>, taking the '+' as an
          occurrence indicator and the '-' as a subtraction operator. To force the interpretation of
          "+" as an addition operator (and the corresponding interpretation of the "-" as a unary
          minus), parentheses may be used: the form <code role="parse-test" nobreak="false">(4 treat as item()) +
            -5</code> surrounds the <nt def="doc-xquery40-SequenceType">SequenceType<!--$spec = xquery40--></nt> expression with
          parentheses and leads to the desired interpretation.</p>
                  <p>
                     <code nobreak="false">function () as xs:string *</code> is interpreted as <code nobreak="false">function () as (xs:string
            *)</code>, not as <code nobreak="false">(function () as xs:string) *</code>. Parentheses can be used as
          shown to force the latter interpretation.</p>
                  <p>This rule has as a consequence that certain forms which would otherwise be syntactically
          valid and unambiguous are not recognized: in <code nobreak="false">4 treat as item() + 5</code>, the <code nobreak="false">"+"</code> is taken as
          an <nt def="prod-xquery40-OccurrenceIndicator">OccurrenceIndicator<!--$spec = xquery40--></nt>, and not as an operator, which
          means this is not a syntactically valid expression.</p>
               </constraintnote>
               <!--<constraintnote id="constructor-op-brace" type="xgc">
        
        <head>constructor-op-brace</head>
        
        <p>In XQuery, there are two ways that the expression <code>element otherwise {}</code> could be parsed:
        it could be treated as a computed element constructor creating an element named <code>otherwise</code>
        with empty content, or it could be treated as an attempt to select a child node named <code>element</code>,
        returning an empty map if no such node exists.</p>
        
        <p>This ambiguity has been introduced in 4.0 as a consequence of allowing map constructors to be
        written without the leading <code>map</code> keyword. The ambiguity is therefore resolved to retain
        the XQuery 3.1 interpretation, constructing an element named <code>otherwise</code>.</p>
        
        <p>More generally, if an expression starts with the three tokens (<var>K</var> <var>N</var> "{"), 
          where <var>K</var> is one of <code>element</code>, <code>attribute</code>, 
          <code>processing-instruction</code>, or <code>namespace</code>, and <var>N</var> is an
          <code>NCName</code> that could be interpreted as a binary operator (for example <code>div</code> or
          <code>otherwise</code>) then the expression is parsed as a node construction expression,
          creating a node of kind <var>K</var> whose name is <var>N</var>.</p>
        
        <p>This ambiguity does not arise in XPath, which does not recognize computed node constructor
        expressions. However, in the interests of compatibility between XPath and XQuery, and to retain
        the option of adding computed node constructors to XPath in the future, XPath processors
        <code>should</code> reject such expressions as invalid.</p>
        
      </constraintnote>-->
            </div3>
            <div3 id="notes-on-parsing">
               <head>Grammar Notes</head>
               <p>This section contains general notes on the EBNF productions, which may be helpful in
        understanding how to interpret and implement the EBNF. These notes are not normative. The
        notes below are referenced from the right side of the production, with the notation:
          <emph>/* gn: &lt;id&gt; */</emph>.</p>
               <note>
                  <glist>
                     <gitem id="parse-note-parens">
                        <label>grammar-note: parens</label>
                        <def>
                           <p>Lookahead is required to distinguish a <nt def="doc-xquery40-FunctionCall">FunctionCall<!--$spec = xquery40--></nt> from
                an EQName or keyword followed by a <phrase role="xquery">
                                 <nt def="prod-xquery40-Pragma">Pragma<!--$spec = xquery40--></nt> or </phrase>
                              <nt def="doc-xquery40-Comment">Comment<!--$spec = xquery40--></nt>. For example: <code role="parse-test" nobreak="false">address (: this
                  may be empty :)</code> may be mistaken for a call to a function named "address"
                unless this lookahead is employed. Another example is <code role="parse-test" nobreak="false">for (:
                  whom the bell :) $tolls in 3 return $tolls</code>, where the keyword "for" must
                not be mistaken for a function name.</p>
                        </def>
                     </gitem>
                     <gitem id="parse-note-comments">
                        <label>grammar-note: comments</label>
                        <def>
                           <p>Comments are allowed everywhere that <termref def="IgnorableWhitespace">ignorable
                  whitespace</termref> is allowed, and the <nt def="doc-xquery40-Comment">Comment<!--$spec = xquery40--></nt> symbol
                does not explicitly appear on the right-hand side of the grammar (except in its own
                production). See <specref ref="DefaultWhitespaceHandling"/>. <phrase role="xquery">Note that comments are not allowed in direct constructor content, though they are
                  allowed in nested <nt def="doc-xquery40-EnclosedExpr"> EnclosedExprs<!--$spec = xquery40--></nt>.</phrase>
                           </p>
                           <p>A comment can contain nested comments, as long as all <code nobreak="false">"(:"</code> and <code nobreak="false">":)"</code> patterns are
                balanced, no matter where they occur within the outer comment.</p>
                           <note>
                              <p>Lexical analysis may typically handle nested comments by incrementing a counter
                  for each <code nobreak="false">"(:"</code> pattern, and decrementing the counter for each <code nobreak="false">":)"</code> pattern. The
                  comment does not terminate until the counter is back to zero.</p>
                           </note>
                           <p>Some illustrative examples:</p>
                           <ulist>
                              <item>
                                 <p>
                                    <code nobreak="false">(: commenting out a (: comment :) may be confusing, but often helpful
                      :)</code> is a syntactically valid <nt def="doc-xquery40-Comment">Comment<!--$spec = xquery40--></nt>, since balanced nesting of comments
                    is allowed.</p>
                              </item>
                              <item>
                                 <p>
                                    <code role="parse-test" nobreak="false">"this is just a string :)"</code> is a syntactically
                    valid expression. However, <code nobreak="false">(: "this is just a string :)" :)</code> will
                    cause a syntax error. Likewise, <code role="parse-test" nobreak="false">"this is another string
                      (:"</code> is a syntactically valid expression, but <code nobreak="false">(: "this is another
                      string (:" :)</code> will cause a syntax error. It is a limitation of nested
                    comments that literal content can cause unbalanced nesting of comments.</p>
                              </item>
                              <item>
                                 <p>
                                    <code role="parse-test" nobreak="false">for (: set up loop :) $i in $x return $i</code> is
                    syntactically valid, ignoring the comment.</p>
                              </item>
                              <item>
                                 <p>
                                    <code role="parse-test" nobreak="false">5 instance (: strange place for a comment :) of
                      xs:integer</code> is also syntactically valid.</p>
                              </item>
                              <item role="xquery">
                                 <p>
                                    <code nobreak="false">
                      &lt;eg (: an example:)&gt;{$i//title}&lt;/eg&gt;
                    </code> is not syntactically valid.</p>
                              </item>
                              <item role="xquery">
                                 <p>
                                    <code role="parse-test" nobreak="false">
                      &lt;eg&gt; (: an example:) &lt;/eg&gt;
                    </code> is syntactically valid, but the characters that look like a comment are
                    in fact literal element content.</p>
                              </item>
                           </ulist>
                        </def>
                     </gitem>
                  </glist>
               </note>
            </div3>
         </div2>
         <div2 id="productions-derived-from-XML">
            <head>Productions Derived from XML</head>
            <p>Some productions are defined by reference to the XML and XML Names specifications (e.g.
      <bibref ref="XML"/> and <bibref ref="XMLNAMES"/>, or <bibref ref="XML1.1"/> and <bibref ref="XMLNAMES11"/>. <phrase role="xquery">It is implementation-defined</phrase> which version of these specifications is
      used; it is recommended that the latest applicable version be used (even if it is published
      later than this specification).</p>
            <p role="xquery">It is <termref def="dt-implementation-defined">
      implementation-defined</termref> whether the lexical rules of <bibref ref="XML"/> and
      <bibref ref="XMLNAMES"/> are followed, or alternatively, the lexical rules of <bibref ref="XML1.1"/> and <bibref ref="XMLNAMES11"/> are followed. Implementations that support the
      full <bibref ref="XML1.1"/> character set <termref def="should">SHOULD</termref>, for purposes
      of interoperability, provide a mode that follows only the <bibref ref="XML"/> and <bibref ref="XMLNAMES"/> lexical rules.</p>
         </div2>
         <div2 id="lexical-structure">
            <head>Lexical structure</head>
            <changes>
               <change issue="327" PR="519" date="2023-05-30">
        The rules for tokenization have been largely rewritten. In some cases the revised specification may
        affect edge cases that were handled in different ways by different 3.1 processors, which could lead
        to incompatible behavior.
      </change>
            </changes>
            <p diff="add" at="2023-05-22">This section describes how an XQuery 4.0 text is tokenized prior to parsing.</p>
            <p>All keywords are case sensitive. Keywords are not reserved—that is, any <termref def="dt-qname">lexical QName</termref> may duplicate a keyword except as noted in <specref ref="id-reserved-fn-names"/>.</p>
            <p diff="add" at="2023-05-22">Tokenizing an input string is a process that follows the following rules:</p>
            <ulist diff="add" at="2023-05-22">
               <item>
                  <p>
                     <termdef id="dt-ordinary-production-rule" term="ordinary production rule">An <term>ordinary production rule</term> 
        is a production rule in <specref ref="id-grammar"/> that is not annotated <code nobreak="false">ws:explicit</code>.</termdef>
                  </p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-literal-terminal" term="literal terminal">A <term>literal terminal</term> is a token appearing as a string 
        in quotation marks on the right-hand side of an <termref def="dt-ordinary-production-rule"/>.</termdef>
                  </p>
                  <note>
                     <p>Strings that appear in other production rules do not qualify.
        <phrase role="xquery">For example, <code nobreak="false">"]]&gt;"</code> is not a literal terminal, because it appears only in the rule
        <nt def="prod-xquery40-CDataSection">CDataSection<!--$spec = xquery40--></nt>, which is not an ordinary production rule; similarly <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$spec = xquery40--></nt>
          does not qualify because it appears only in <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$spec = xquery40--></nt>, and <code nobreak="false">"0x"</code> does not qualify
        because it appears only in <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral<!--$spec = xquery40--></nt>.</phrase>
                     </p>
                  </note>
                  <p>
          The <termref def="dt-literal-terminal">literal terminals</termref>  in XQuery 4.0 are: <code>!</code>
                     <code>!=</code>
                     <code>#</code>
                     <code>$</code>
                     <code>%</code>
                     <code>(</code>
                     <code>)</code>
                     <code>*</code>
                     <code>+</code>
                     <code>,</code>
                     <code>.</code>
                     <code>..</code>
                     <code>/</code>
                     <code>//</code>
                     <code>:</code>
                     <code>::</code>
                     <code>:=</code>
                     <code>;</code>
                     <code>&lt;</code>
                     <code>&lt;&lt;</code>
                     <code>&lt;=</code>
                     <code>=</code>
                     <code>=!&gt;</code>
                     <code>=&gt;</code>
                     <code>=?&gt;</code>
                     <code>&gt;</code>
                     <code>&gt;=</code>
                     <code>&gt;&gt;</code>
                     <code>?</code>
                     <code>?[</code>
                     <code>@</code>
                     <code>[</code>
                     <code>]</code>
                     <code>`{</code>
                     <code>{</code>
                     <code>|</code>
                     <code>||</code>
                     <code>}</code>
                     <code>}`</code>
                     <code>×</code>
                     <code>÷</code>
                     <code>-</code>
                     <code>-&gt;</code>
                     <code>allowing</code>
                     <code>ancestor</code>
                     <code>ancestor-or-self</code>
                     <code>and</code>
                     <code>array</code>
                     <code>as</code>
                     <code>ascending</code>
                     <code>at</code>
                     <code>attribute</code>
                     <code>base-uri</code>
                     <code>boundary-space</code>
                     <code>by</code>
                     <code>case</code>
                     <code>cast</code>
                     <code>castable</code>
                     <code>catch</code>
                     <code>child</code>
                     <code>collation</code>
                     <code>comment</code>
                     <code>construction</code>
                     <code>context</code>
                     <code>copy-namespaces</code>
                     <code>count</code>
                     <code>decimal-format</code>
                     <code>decimal-separator</code>
                     <code>declare</code>
                     <code>default</code>
                     <code>descendant</code>
                     <code>descendant-or-self</code>
                     <code>descending</code>
                     <code>digit</code>
                     <code>div</code>
                     <code>document</code>
                     <code>document-node</code>
                     <code>element</code>
                     <code>else</code>
                     <code>empty</code>
                     <code>empty-sequence</code>
                     <code>encoding</code>
                     <code>end</code>
                     <code>enum</code>
                     <code>eq</code>
                     <code>every</code>
                     <code>except</code>
                     <code>exponent-separator</code>
                     <code>external</code>
                     <code>false</code>
                     <code>finally</code>
                     <code>fixed</code>
                     <code>fn</code>
                     <code>following</code>
                     <code>following-or-self</code>
                     <code>following-sibling</code>
                     <code>following-sibling-or-self</code>
                     <code>follows</code>
                     <code>follows-or-is</code>
                     <code>for</code>
                     <code>function</code>
                     <code>ge</code>
                     <code>get</code>
                     <code>gnode</code>
                     <code>greatest</code>
                     <code>group</code>
                     <code>grouping-separator</code>
                     <code>gt</code>
                     <code>idiv</code>
                     <code>if</code>
                     <code>import</code>
                     <code>in</code>
                     <code>infinity</code>
                     <code>inherit</code>
                     <code>instance</code>
                     <code>intersect</code>
                     <code>is</code>
                     <code>is-not</code>
                     <code>item</code>
                     <code>jnode</code>
                     <code>key</code>
                     <code>lax</code>
                     <code>le</code>
                     <code>least</code>
                     <code>let</code>
                     <code>lt</code>
                     <code>map</code>
                     <code>member</code>
                     <code>minus-sign</code>
                     <code>mod</code>
                     <code>module</code>
                     <code>namespace</code>
                     <code>namespace-node</code>
                     <code>NaN</code>
                     <code>ne</code>
                     <code>next</code>
                     <code>no-inherit</code>
                     <code>no-preserve</code>
                     <code>node</code>
                     <code>of</code>
                     <code>only</code>
                     <code>option</code>
                     <code>or</code>
                     <code>order</code>
                     <code>ordered</code>
                     <code>ordering</code>
                     <code>otherwise</code>
                     <code>parent</code>
                     <code>pattern-separator</code>
                     <code>per-mille</code>
                     <code>percent</code>
                     <code>precedes</code>
                     <code>precedes-or-is</code>
                     <code>preceding</code>
                     <code>preceding-or-self</code>
                     <code>preceding-sibling</code>
                     <code>preceding-sibling-or-self</code>
                     <code>preserve</code>
                     <code>previous</code>
                     <code>processing-instruction</code>
                     <code>record</code>
                     <code>return</code>
                     <code>satisfies</code>
                     <code>schema</code>
                     <code>schema-attribute</code>
                     <code>schema-element</code>
                     <code>self</code>
                     <code>sliding</code>
                     <code>some</code>
                     <code>stable</code>
                     <code>start</code>
                     <code>strict</code>
                     <code>strip</code>
                     <code>switch</code>
                     <code>text</code>
                     <code>then</code>
                     <code>to</code>
                     <code>treat</code>
                     <code>true</code>
                     <code>try</code>
                     <code>tumbling</code>
                     <code>type</code>
                     <code>typeswitch</code>
                     <code>union</code>
                     <code>unordered</code>
                     <code>validate</code>
                     <code>value</code>
                     <code>variable</code>
                     <code>version</code>
                     <code>when</code>
                     <code>where</code>
                     <code>while</code>
                     <code>window</code>
                     <code>xquery</code>
                     <code>zero-digit</code> 
                  </p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-variable-terminal" term="variable terminal">A <term>variable terminal</term> is an instance
        of a production rule that is not itself an <termref def="dt-ordinary-production-rule"/> but that is named (directly) on the right-hand
        side of an <termref def="dt-ordinary-production-rule"/>.</termdef>
                  </p>
                  <p>
          The <termref def="dt-variable-terminal">variable terminals</termref> in XQuery 4.0 are: <nt def="prod-xquery40-BinaryIntegerLiteral">BinaryIntegerLiteral</nt>
                     <nt def="prod-xquery40-CDataSection">CDataSection</nt>
                     <nt def="prod-xquery40-DecimalLiteral">DecimalLiteral</nt>
                     <nt def="prod-xquery40-DirCommentConstructor">DirCommentConstructor</nt>
                     <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor</nt>
                     <nt def="prod-xquery40-DirPIConstructor">DirPIConstructor</nt>
                     <nt def="prod-xquery40-DoubleLiteral">DoubleLiteral</nt>
                     <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral</nt>
                     <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral</nt>
                     <code>NCName</code>
                     <nt def="prod-xquery40-Pragma">Pragma</nt>
                     <nt def="prod-xquery40-QName">QName</nt>
                     <nt def="prod-xquery40-StringConstructor">StringConstructor</nt>
                     <nt def="prod-xquery40-StringLiteral">StringLiteral</nt>
                     <nt def="prod-xquery40-StringTemplate">StringTemplate</nt>
                     <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName</nt>
                     <nt def="prod-xquery40-Wildcard">Wildcard</nt> 
                  </p>
               </item>
               <item>
                  <p>
                     <termdef id="dt-complex-terminal" term="complex terminal">A <term>complex terminal</term> is
        a <termref def="dt-variable-terminal"/> whose production rule references, directly or indirectly, an 
        <termref def="dt-ordinary-production-rule"/>.</termdef>
                  </p>
                  <p>
          The <termref def="dt-complex-terminal">complex terminals</termref>  in XQuery 4.0 are: <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor</nt>
                     <nt def="prod-xquery40-Pragma">Pragma</nt>
                     <nt def="prod-xquery40-StringConstructor">StringConstructor</nt>
                     <nt def="prod-xquery40-StringTemplate">StringTemplate</nt> 
                  </p>
                  <note>
                     <p>The significance of complex terminals is that at one level, a complex terminal is treated as a single
      token, but internally it may contain arbitrary expressions that must be parsed using the full EBNF grammar.</p>
                  </note>
               </item>
               <item>
                  <p>Tokenization is the process of splitting the supplied input string into a sequence of terminals, where each
      terminal is either a <termref def="dt-literal-terminal"/> or a <termref def="dt-variable-terminal"/> (which may itself
      be a <termref def="dt-complex-terminal"/>). Tokenization is done by repeating the following steps:</p>
                  <olist>
                     <item>
                        <p>Starting at the current position, skip any whitespace and comments.</p>
                     </item>
                     <item>
                        <p>If the current position is not the end of the input, then
          return the longest <termref def="dt-literal-terminal"/> or <termref def="dt-variable-terminal"/> 
        that can be matched starting at the current position, regardless whether this terminal is valid at this point
        in the grammar. If no such terminal can be identified starting at the current position, or if the terminal that
        is identified is not a valid continuation of the grammar rules, then a syntax error is reported.</p>
                        <note>
                           <p>Here are some examples showing the effect of the longest token rule:</p>
                           <ulist>
                              <item>
                                 <p>The expression <code nobreak="false">map{a:b}</code> is a syntax error. Although there is a 
              tokenization of this string that satisfies the grammar (by treating <code nobreak="false">a</code> and <code nobreak="false">b</code>
              as separate expressions), this tokenization does not satisfy the longest token rule,
              which requires that <code nobreak="false">a:b</code> is interpreted as a single <code nobreak="false">QName</code>.</p>
                              </item>
                              <item>
                                 <p>The expression <code nobreak="false">10 div3</code> is a syntax error. The longest token rule requires that this
              be interpreted as two tokens (<code nobreak="false">"10"</code> and <code nobreak="false">"div3"</code>) even though it would
              be a valid expression if treated as three tokens (<code nobreak="false">"10"</code>, <code nobreak="false">"div"</code>, and <code nobreak="false">"3"</code>).</p>
                              </item>
                              <item>
                                 <p>The expression <code nobreak="false">$x-$y</code> is a syntax error. This is interpreted as four tokens,
              (<code nobreak="false">"$"</code>, <code nobreak="false">"x-"</code>, <code nobreak="false">"$"</code>, and <code nobreak="false">"y"</code>).</p>
                              </item>
                              <!--<item role="xquery"><p>In XQuery, the expression <code>error(#err:XPTY0004)</code> is a syntax error. 
              The presence of <code>(#</code>, without intervening whitespace, indicates the start of a pragma.
              To interpret this as a call on the <function>fn:error</function> function with a <code>QNameLiteral</code> argument,
              whitespace separation is needed: <code>error( #err:XPTY0004 )</code>.</p></item>-->
                           </ulist>
                        </note>
                        <note>
                           <p>The lexical production rules for <termref def="dt-variable-terminal">variable terminals</termref>
        have been designed so that there is minimal need for backtracking. For example, if the next terminal
        starts with <code nobreak="false">"0x"</code>, then it can only be either a <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral<!--$spec = xquery40--></nt> or an error;
        if it starts with <code nobreak="false">"`"</code> (and not with <code nobreak="false">"```"</code>) then it can only be a
          <nt def="doc-xquery40-StringTemplate">StringTemplate<!--$spec = xquery40--></nt> or an error. <phrase role="xquery">Direct element constructors
          and pragmas in XQuery, however, need special treatment, described below.</phrase>
                           </p>
                           <p>This convention, together with the rules for whitespace separation of tokens (see <specref ref="id-terminal-delimitation"/>) 
          means that the longest-token rule does not normally result in any need for backtracking. For example, suppose 
          that a <termref def="dt-variable-terminal"/> has been identified as a <nt def="doc-xquery40-StringTemplate">StringTemplate<!--$spec = xquery40--></nt> by examining
          its first few characters. If the construct turns out not to be a valid <nt def="doc-xquery40-StringTemplate">StringTemplate<!--$spec = xquery40--></nt>, 
          an error can be reported without first considering whether there is some shorter token that might be returned instead.</p>
                        </note>
                     </item>
                  </olist>
               </item>
               <item role="xquery">
                  <p>Tokenization requires special care when the current character is
      <char>U+003C</char>:</p>
                  <ulist>
                     <item>
                        <p>If the following character is <char>U+003D</char> then the token can be identified
          unambiguously as the operator <code nobreak="false">&lt;=</code>.</p>
                     </item>
                     <item>
                        <p>If the following character is <char>U+003C</char> then the token can be identified
          unambiguously as the operator <code nobreak="false">&lt;&lt;</code>.</p>
                     </item>
                     <item>
                        <p>If the following character is <char>U+0021</char> then the token can be identified
          unambiguously as being a <nt def="prod-xquery40-DirCommentConstructor">DirCommentConstructor<!--$spec = xquery40--></nt> (a
            <nt def="prod-xquery40-CDataSection">CDataSection<!--$spec = xquery40--></nt>, which also starts with <code nobreak="false">&lt;!</code> can appear
            only within a direct element constructor, not as a free-standing token).</p>
                     </item>
                     <item>
                        <p>If the following character is <char>U+003F</char>, then the token is identified
          as a <nt def="doc-xquery40-DirPIConstructor">DirPIConstructor<!--$spec = xquery40--></nt> if and only if a match for the
          relevant production (<code nobreak="false">"&lt;?" PITarget (S DirPIContents)? "?&gt;"</code>) is found. If there
          is no such match, then the string <code nobreak="false">"&lt;?"</code> is identified as a less-than operator
            followed by a lookup operator.</p>
                     </item>
                     <item>
                        <p>If the following character is a <xnt xmlns:xlink="http://www.w3.org/1999/xlink"
                                href="http://www.w3.org/TR/REC-xml/#NameStartChar"
                                xlink:type="simple">NameStartChar</xnt>
          then the token is identified as a <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor<!--$spec = xquery40--></nt> if and only
          if a match for the leading part of a <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor<!--$spec = xquery40--></nt> is
          found: specifically if a substring starting at the <char>U+003C</char> character matches one of
          the following regular expressions:</p>
                        <slist>
                           <sitem>
                              <code nobreak="false">^&lt;\i\c*\s*&gt;</code> (as in <code nobreak="false">&lt;element&gt;...</code>)</sitem>
                           <sitem>
                              <code nobreak="false">^&lt;\i\c*\s*/&gt;</code>(as in <code nobreak="false">&lt;element/&gt;</code>)</sitem>
                           <sitem>
                              <code nobreak="false">^&lt;\i\c*\s+\i\c*\s*=</code>(as in <code nobreak="false">&lt;element att=...</code>)</sitem>
                        </slist>
                        <p>If the content matches one of these regular expressions but further analysis shows that the subsequent
            content does not satisfy the <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor<!--$spec = xquery40--></nt> production,
            then a static error is reported.</p>
                        <p>If the content does not match any of these regular expressions then the token is identified
              as the less-than operator <code nobreak="false">&lt;</code>.</p>
                     </item>
                     <item>
                        <p>If the following character is any other character then the token can be identified
          unambiguously as the less-than operator <code nobreak="false">&lt;</code>.</p>
                     </item>
                  </ulist>
                  <p>This analysis is done without regard to the syntactic context of the <char>U+003C</char> character.
        However, a tokenizer <rfc2119>may</rfc2119> avoid looking for a <nt def="doc-xquery40-DirPIConstructor">DirPIConstructor<!--$spec = xquery40--></nt>
        or <nt def="prod-xquery40-DirElemConstructor">DirElemConstructor<!--$spec = xquery40--></nt> if it knows that such a constructor cannot appear
        in the current syntactic context.</p>
                  <note>
                     <p>The rules here are described much more precisely than in XQuery 3.1, and the results
        in edge cases might be incompatible with some XQuery 3.1 processors.</p>
                  </note>
                  <note>
                     <p>To avoid potential confusion, simply add whitespace after any less-than operator.</p>
                  </note>
               </item>
               <item role="xquery">
                  <p>In XQuery the initial characters <code nobreak="false">(#</code> followed by whitespace are taken to signal the start
      of a <nt def="prod-xquery40-Pragma">Pragma<!--$spec = xquery40--></nt>. No backtracking takes place if this turns out not to be a valid
      pragma. The whitespace is necessary to distinguish a pragma from other occurrences of <code nobreak="false">(#</code>, for example
        a parenthesized QName literal.</p>
               </item>
               <item>
                  <p>Tokenization unambiguously identifies the boundaries of the terminals in the input, and this
        can be achieved without backtracking or lookahead. However, tokenization does
      not unambiguously classify each terminal. For example, it might identify the string <code nobreak="false">"div"</code> as a terminal, but it does not
      resolve whether this is the operator symbol <code nobreak="false">div</code>, or an <code nobreak="false">NCName</code> 
        or <code nobreak="false">QName</code> used as a 
      node test or as a variable or function name. Classification of terminals generally requires information about the
      grammatical context, and in some cases requires lookahead.</p>
                  <note>
                     <p>Operationally, classification of terminals may be done either in the tokenizer or the parser, or
      in some combination of the two. For example, according to the EBNF, the expression 
        <code nobreak="false">"parent::x"</code> is made up of three
      tokens, <code nobreak="false">"parent"</code>, <code nobreak="false">"::"</code>, and <code nobreak="false">"x"</code>. The name <code nobreak="false">"parent"</code>
        can be classified as an axis name as soon as the following token <code nobreak="false">"::"</code> is recognized, and this
      might be done either in the tokenizer or in the parser. (Note that whitespace and comments are allowed
      both before and after <code nobreak="false">"::"</code>.)</p>
                  </note>
               </item>
               <item>
                  <p>In the case of a <termref def="dt-complex-terminal"/>, identifying the end of the complex terminal
      typically involves invoking the parser to process any embedded expressions. Tokenization, as described
      here, is therefore a recursive process. But other implementations are possible.</p>
               </item>
            </ulist>
            <note>
               <p>Previous versions of this specification included the statement: 
      <emph>When tokenizing, the longest possible match that is consistent with the EBNF is used.</emph>
               </p>
               <p>Different processors are known to have interpreted this in different ways. One interpretation,
      for example, was that the expression <code nobreak="false">10 div-3</code> should be split into four tokens (<code nobreak="false">10</code>,
      <code nobreak="false">div</code>, <code nobreak="false">-</code>, <code nobreak="false">3</code>) on the grounds that any other tokenization would give a
      result that was inconsistent with the EBNF grammar. Other processors report a syntax error on this example.</p>
               <p>This rule has therefore been rewritten in version 4.0. Tokenization is now entirely insensitive to the
      grammatical context; <code nobreak="false">div-3</code> is recognized as a single token even though this results in a syntax
      error. For some implementations this may mean that expressions that were accepted in earlier releases
      are no longer accepted in 4.0.</p>
               <p role="xquery">A more subtle example is: <code nobreak="false">(. &lt;?b ) cast as xs:integer?&gt; 0)</code>
      in which <code nobreak="false">&lt;?b ) cast as xs:integer?&gt;</code> is recognized as a single token (a direct
      processing instruction constructor) even though such a token cannot validly appear in this
      grammatical context.</p>
            </note>
            <div3 id="terminal-symbols">
               <head>Terminal Symbols</head>
               <scrap headstyle="show">
                  <head/>
                  <prod id="prod-xquery40-IntegerLiteral">
                     <lhs>IntegerLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-HexIntegerLiteral">
                     <lhs>HexIntegerLiteral</lhs>
                     <rhs>"0x"  <nt def="prod-xquery40-HexDigits">HexDigits<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-BinaryIntegerLiteral">
                     <lhs>BinaryIntegerLiteral</lhs>
                     <rhs>"0b"  <nt def="prod-xquery40-BinaryDigits">BinaryDigits<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DecimalLiteral">
                     <lhs>DecimalLiteral</lhs>
                     <rhs>("."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>)  |  (<nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>  "."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>?)</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DoubleLiteral">
                     <lhs>DoubleLiteral</lhs>
                     <rhs>(("."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>)  |  (<nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>  ("."  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>?)?))  [eE]  [+-]?  <nt def="prod-xquery40-Digits">Digits<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-StringLiteral">
                     <lhs>StringLiteral</lhs>
                     <rhs>
                        <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-AposStringLiteral">
                     <lhs>AposStringLiteral</lhs>
                     <rhs>"'"  (<nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EscapeApos">EscapeApos<!--$idref_lang_part = xquery40- --></nt>  |  [^'&amp;])*  "'"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-QuotStringLiteral">
                     <lhs>QuotStringLiteral</lhs>
                     <rhs>'"'  (<nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-EscapeQuot">EscapeQuot<!--$idref_lang_part = xquery40- --></nt>  |  [^"&amp;])*  '"'</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-URIQualifiedName">
                     <lhs>URIQualifiedName</lhs>
                     <rhs>
                        <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>  (<nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>  ":")?  <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                     </rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-BracedURILiteral">
                     <lhs>BracedURILiteral</lhs>
                     <rhs>"Q"  "{"  (<nt def="prod-xquery40-PredefinedEntityRef">PredefinedEntityRef<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-CharRef">CharRef<!--$idref_lang_part = xquery40- --></nt>  |  [^&amp;{}])*  "}"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-PredefinedEntityRef">
                     <lhs>PredefinedEntityRef</lhs>
                     <rhs>"&amp;"  ("lt"  |  "gt"  |  "amp"  |  "quot"  |  "apos")  ";"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-EscapeQuot">
                     <lhs>EscapeQuot</lhs>
                     <rhs>'""'</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-EscapeApos">
                     <lhs>EscapeApos</lhs>
                     <rhs>"''"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-ElementContentChar">
                     <lhs>ElementContentChar</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - [{}&lt;&amp;])</rhs>
                  </prod>

                  <prod id="prod-xquery40-QuotAttrContentChar">
                     <lhs>QuotAttrContentChar</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - ["{}&lt;&amp;])</rhs>
                  </prod>

                  <prod id="prod-xquery40-AposAttrContentChar">
                     <lhs>AposAttrContentChar</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt> - ['{}&lt;&amp;])</rhs>
                  </prod>

                  <prod id="prod-xquery40-Comment">
                     <lhs>Comment</lhs>
                     <rhs>"(:"  (<nt def="prod-xquery40-CommentContents">CommentContents<!--$idref_lang_part = xquery40- --></nt>  |  <nt def="prod-xquery40-Comment">Comment<!--$idref_lang_part = xquery40- --></nt>)*  ":)"</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                     <com>
                        <loc href="#parse-note-comments">gn: comments</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-PITarget">
                     <lhs>PITarget</lhs>
                     <rhs>
                        <xnt ref="NT-PITarget" spec="XML">[http://www.w3.org/TR/REC-xml#NT-PITarget]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-CharRef">
                     <lhs>CharRef</lhs>
                     <rhs>
                        <xnt ref="NT-CharRef" spec="XML">[http://www.w3.org/TR/REC-xml#NT-CharRef]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-QName">
                     <lhs>QName</lhs>
                     <rhs>
                        <xnt ref="NT-QName" spec="Names">[http://www.w3.org/TR/REC-xml-names/#NT-QName]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-NCName">
                     <lhs>NCName</lhs>
                     <rhs>
                        <xnt ref="NT-NCName" spec="Names">[http://www.w3.org/TR/REC-xml-names/#NT-NCName]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-S">
                     <lhs>S</lhs>
                     <rhs>
                        <xnt ref="NT-S" spec="XML">[http://www.w3.org/TR/REC-xml#NT-S]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-Char">
                     <lhs>Char</lhs>
                     <rhs>
                        <xnt ref="NT-Char" spec="XML">[http://www.w3.org/TR/REC-xml#NT-Char]</xnt>
                     </rhs>
                     <com>
                        <loc href="#parse-note-xml-version">xgc: xml-version</loc>
                     </com>
                  </prod>
               </scrap>
               <p>The following symbols are used only in the definition of terminal symbols; they are not
        terminal symbols in the grammar of <specref ref="id-grammar"/>.</p>
               <scrap headstyle="show">
                  <head/>
                  <prod id="prod-xquery40-Digits">
                     <lhs>Digits</lhs>
                     <rhs>
                        <nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>  |  "_")*  <nt def="prod-xquery40-DecDigit">DecDigit<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-DecDigit">
                     <lhs>DecDigit</lhs>
                     <rhs>[0-9]</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-HexDigits">
                     <lhs>HexDigits</lhs>
                     <rhs>
                        <nt def="prod-xquery40-HexDigit">HexDigit<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-HexDigit">HexDigit<!--$idref_lang_part = xquery40- --></nt>  |  "_")*  <nt def="prod-xquery40-HexDigit">HexDigit<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-HexDigit">
                     <lhs>HexDigit</lhs>
                     <rhs>[0-9a-fA-F]</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-BinaryDigits">
                     <lhs>BinaryDigits</lhs>
                     <rhs>
                        <nt def="prod-xquery40-BinaryDigit">BinaryDigit<!--$idref_lang_part = xquery40- --></nt>  ((<nt def="prod-xquery40-BinaryDigit">BinaryDigit<!--$idref_lang_part = xquery40- --></nt>  |  "_")*  <nt def="prod-xquery40-BinaryDigit">BinaryDigit<!--$idref_lang_part = xquery40- --></nt>)?</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-BinaryDigit">
                     <lhs>BinaryDigit</lhs>
                     <rhs>[01]</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>

                  <prod id="prod-xquery40-CommentContents">
                     <lhs>CommentContents</lhs>
                     <rhs>(<nt def="prod-xquery40-Char">Char<!--$idref_lang_part = xquery40- --></nt>+ - (Char* ('(:' | ':)') Char*))</rhs>
                     <com>
                        <loc href="#ws-explicit">ws: explicit</loc>
                     </com>
                  </prod>
               </scrap>
            </div3>
            <div3 id="id-terminal-delimitation">
               <head>Terminal Delimitation</head>
               <p>XQuery 4.0 expressions consist of <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                       href="#terminal-symbols"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">terminal symbols</loc> and
          <termref def="symbolseparators">symbol separators</termref>.</p>
               <p>
                  <phrase diff="add" at="2023-05-22">
                     <termref def="dt-literal-terminal">Literal</termref> 
        and <termref def="dt-variable-terminal">variable</termref>
                  </phrase>
        terminal symbols are of two kinds: delimiting and non-delimiting.</p>
               <!-- The next paragraph is "filled in" by various stylesheets used to generate the "assembled" source files. -->
               <p>
                  <termdef id="delimiting-token" term="delimiting terminal symbol">The <term>delimiting
            terminal symbols</term> are: <code>!</code>
                     <code>!=</code>
                     <code>#</code>
                     <code>#)</code>
                     <code>$</code>
                     <code>%</code>
                     <code>(</code>
                     <code>(#</code>
                     <code>)</code>
                     <code>*</code>
                     <code>*:</code>
                     <code>+</code>
                     <code>,</code>
                     <code>-</code>
                     <code>--&gt;</code>
                     <code>-&gt;</code>
                     <code>.</code>
                     <code>..</code>
                     <code>/</code>
                     <code>//</code>
                     <code>/&gt;</code>
                     <code>:</code>
                     <code>:*</code>
                     <code>::</code>
                     <code>:=</code>
                     <code>;</code>
                     <code>&lt;</code>
                     <code>&lt;!--</code>
                     <code>&lt;![CDATA[</code>
                     <code>&lt;/</code>
                     <code>&lt;&lt;</code>
                     <code>&lt;=</code>
                     <code>&lt;?</code>
                     <code>=</code>
                     <code>=!&gt;</code>
                     <code>=&gt;</code>
                     <code>=?&gt;</code>
                     <code>&gt;</code>
                     <code>&gt;=</code>
                     <code>&gt;&gt;</code>
                     <code>?</code>
                     <code>?&gt;</code>
                     <code>?[</code>
                     <code>@</code>
                     <code>[</code>
                     <code>]</code>
                     <code>]]&gt;</code>
                     <code>]``</code>
                     <code>`</code>
                     <code>``</code>
                     <code>``[</code>
                     <code>`{</code>
                     <code>{</code>
                     <code>{{</code>
                     <code>|</code>
                     <code>||</code>
                     <code>}</code>
                     <code>}`</code>
                     <code>}}</code>
                     <code>×</code>
                     <code>÷</code>
                     <nt def="prod-xquery40-AposStringLiteral">AposStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-QuotStringLiteral">QuotStringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-S">S<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-StringLiteral">StringLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$idref_lang_part = xquery40- --></nt>
                  </termdef>
               </p>
               <!-- The next paragraph is "filled in" by various stylesheets used to generate the "assembled" source files. -->
               <p>
                  <termdef id="non-delimiting-token" term="non-delimiting terminal symbol">The
            <term>non-delimiting terminal symbols</term> are: <code>allowing</code>
                     <code>ancestor</code>
                     <code>ancestor-or-self</code>
                     <code>and</code>
                     <code>array</code>
                     <code>as</code>
                     <code>ascending</code>
                     <code>at</code>
                     <code>attribute</code>
                     <code>base-uri</code>
                     <code>boundary-space</code>
                     <code>by</code>
                     <code>case</code>
                     <code>cast</code>
                     <code>castable</code>
                     <code>catch</code>
                     <code>child</code>
                     <code>collation</code>
                     <code>comment</code>
                     <code>construction</code>
                     <code>context</code>
                     <code>copy-namespaces</code>
                     <code>count</code>
                     <code>decimal-format</code>
                     <code>decimal-separator</code>
                     <code>declare</code>
                     <code>default</code>
                     <code>descendant</code>
                     <code>descendant-or-self</code>
                     <code>descending</code>
                     <code>digit</code>
                     <code>div</code>
                     <code>document</code>
                     <code>document-node</code>
                     <code>element</code>
                     <code>else</code>
                     <code>empty</code>
                     <code>empty-sequence</code>
                     <code>encoding</code>
                     <code>end</code>
                     <code>enum</code>
                     <code>eq</code>
                     <code>every</code>
                     <code>except</code>
                     <code>exponent-separator</code>
                     <code>external</code>
                     <code>false</code>
                     <code>finally</code>
                     <code>fixed</code>
                     <code>fn</code>
                     <code>following</code>
                     <code>following-or-self</code>
                     <code>following-sibling</code>
                     <code>following-sibling-or-self</code>
                     <code>follows</code>
                     <code>follows-or-is</code>
                     <code>for</code>
                     <code>function</code>
                     <code>ge</code>
                     <code>get</code>
                     <code>gnode</code>
                     <code>greatest</code>
                     <code>group</code>
                     <code>grouping-separator</code>
                     <code>gt</code>
                     <code>idiv</code>
                     <code>if</code>
                     <code>import</code>
                     <code>in</code>
                     <code>infinity</code>
                     <code>inherit</code>
                     <code>instance</code>
                     <code>intersect</code>
                     <code>is</code>
                     <code>is-not</code>
                     <code>item</code>
                     <code>jnode</code>
                     <code>key</code>
                     <code>lax</code>
                     <code>le</code>
                     <code>least</code>
                     <code>let</code>
                     <code>lt</code>
                     <code>map</code>
                     <code>member</code>
                     <code>minus-sign</code>
                     <code>mod</code>
                     <code>module</code>
                     <code>namespace</code>
                     <code>namespace-node</code>
                     <code>NaN</code>
                     <code>ne</code>
                     <code>next</code>
                     <code>no-inherit</code>
                     <code>no-preserve</code>
                     <code>node</code>
                     <code>of</code>
                     <code>only</code>
                     <code>option</code>
                     <code>or</code>
                     <code>order</code>
                     <code>ordered</code>
                     <code>ordering</code>
                     <code>otherwise</code>
                     <code>parent</code>
                     <code>pattern-separator</code>
                     <code>per-mille</code>
                     <code>percent</code>
                     <code>precedes</code>
                     <code>precedes-or-is</code>
                     <code>preceding</code>
                     <code>preceding-or-self</code>
                     <code>preceding-sibling</code>
                     <code>preceding-sibling-or-self</code>
                     <code>preserve</code>
                     <code>previous</code>
                     <code>processing-instruction</code>
                     <code>record</code>
                     <code>return</code>
                     <code>satisfies</code>
                     <code>schema</code>
                     <code>schema-attribute</code>
                     <code>schema-element</code>
                     <code>self</code>
                     <code>sliding</code>
                     <code>some</code>
                     <code>stable</code>
                     <code>start</code>
                     <code>strict</code>
                     <code>strip</code>
                     <code>switch</code>
                     <code>text</code>
                     <code>then</code>
                     <code>to</code>
                     <code>treat</code>
                     <code>true</code>
                     <code>try</code>
                     <code>tumbling</code>
                     <code>type</code>
                     <code>typeswitch</code>
                     <code>union</code>
                     <code>unordered</code>
                     <code>validate</code>
                     <code>value</code>
                     <code>variable</code>
                     <code>version</code>
                     <code>when</code>
                     <code>where</code>
                     <code>while</code>
                     <code>window</code>
                     <code>xquery</code>
                     <code>zero-digit</code>
                     <nt def="prod-xquery40-BinaryIntegerLiteral">BinaryIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-DecimalLiteral">DecimalLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-DoubleLiteral">DoubleLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-HexIntegerLiteral">HexIntegerLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-IntegerLiteral">IntegerLiteral<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-NCName">NCName<!--$idref_lang_part = xquery40- --></nt>
                     <nt def="prod-xquery40-QName">QName<!--$idref_lang_part = xquery40- --></nt>
                  </termdef>
               </p>
               <p>
                  <termdef id="symbolseparators" term="symbol separators">
                     <termref def="Whitespace">Whitespace</termref> and <nt def="doc-xquery40-Comment">Comments<!--$spec = xquery40--></nt>
          function as <term>symbol separators</term>. For the most part, they are not mentioned in
          the grammar, and may occur between any two terminal symbols mentioned in the grammar,
          except where that is forbidden by the <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                          href="#ws-explicit"
                          xlink:type="simple"
                          xlink:show="replace"
                          xlink:actuate="onRequest">/* ws: explicit */</loc>
          annotation in the EBNF, or by the <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                          href="#parse-note-xml-version"
                          xlink:type="simple"
                          xlink:show="replace"
                          xlink:actuate="onRequest">/* xgc: xml-version
            */</loc> annotation.</termdef>
               </p>
               <p>
                  <phrase diff="add" at="2023-05-22">As a consequence of the longest token rule (see <specref ref="lexical-structure"/>), </phrase>
        one or more <termref def="symbolseparators">symbol separators</termref>
        are required between two consecutive terminal symbols
        <var>T</var> and <var>U</var> (where <var>T</var> precedes <var>U</var>) when any of the following is true:
      </p>
               <ulist>
                  <item>
                     <p>
                        <var>T</var> and <var>U</var> are both <termref def="non-delimiting-token">non-delimiting terminal symbols</termref>.</p>
                  </item>
                  <item>
                     <p>
                        <var>T</var> is a QName or an NCName and <var>U</var> is <code nobreak="false">"."</code> or <code nobreak="false">"-"</code>.</p>
                  </item>
                  <item>
                     <p>
                        <var>T</var> is a numeric literal and <var>U</var> is <code nobreak="false">"."</code>, or vice versa.</p>
                  </item>
               </ulist>
            </div3>
            <div3 id="id-eol-handling">
               <head>End-of-Line Handling</head>
               <p role="xquery">Prior to parsing, the XQuery 4.0 processor must normalize all line breaks.
        The rules for line breaking follow the rules of <bibref ref="XML"/> or <bibref ref="XML1.1"/>. It is implementation-defined which version is used.</p>
               <div4 id="id-xml10-eol-handling">
                  <head>XML 1.0 End-of-Line Handling</head>
                  <p>For <bibref ref="XML"/> processing, all of the following must be translated to a single
          <char>U+000A</char>:</p>
                  <olist>
                     <item>
                        <p>the two-character sequence <char>U+000D</char>, <char>U+000A</char>;</p>
                     </item>
                     <item>
                        <p>any <char>U+000D</char> character that is not immediately followed by <char>U+000A</char>.</p>
                     </item>
                  </olist>
               </div4>
               <div4 id="id-xml11-eol-handling">
                  <head>XML 1.1 End-of-Line Handling</head>
                  <p>For <bibref ref="XML1.1"/> processing, all of the following must be translated to a
          single <char>U+000A</char> character:</p>
                  <olist>
                     <item>
                        <p>the two-character sequence <char>U+000D</char>, <char>U+000A</char>;</p>
                     </item>
                     <item>
                        <p>the two-character sequence <char>U+000D</char>, <char>U+0085</char>;</p>
                     </item>
                     <item>
                        <p>the single character <char>U+0085</char>;</p>
                     </item>
                     <item>
                        <p>the single character <char>U+2028</char>;</p>
                     </item>
                     <item>
                        <p>any <char>U+000D</char> character that is not immediately followed by <char>U+000A</char> or <char>U+0085</char>.</p>
                     </item>
                  </olist>
                  <p role="xquery">The characters <char>U+0085</char> and <char>U+2028</char> cannot be reliably recognized and translated
          until the <nt def="doc-xquery40-VersionDecl">VersionDecl<!--$spec = xquery40--></nt> declaration (if present) has been
          read.</p>
               </div4>
            </div3>
            <div3 id="whitespace-rules">
               <head>Whitespace Rules</head>
               <div4 id="DefaultWhitespaceHandling">
                  <head>Default Whitespace Handling</head>
                  <p>
                     <termdef id="Whitespace" term="whitespace">A <term>whitespace</term> character is any of
            the characters defined by <xnt xmlns:xlink="http://www.w3.org/1999/xlink"
                             href="http://www.w3.org/TR/REC-xml/#NT-S"
                             xlink:type="simple">
              [http://www.w3.org/TR/REC-xml/#NT-S]</xnt>.</termdef>
                  </p>
                  <p>
                     <termdef term="ignorable whitespace" id="IgnorableWhitespace">
                        <term>Ignorable whitespace</term> consists of any <termref def="Whitespace">whitespace</termref> characters that may occur between <termref def="terminal">terminals</termref>, unless these characters occur in the context of a production
            marked with a <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                             href="#ExplicitWhitespaceHandling"
                             xlink:type="simple"
                             xlink:show="replace"
                             xlink:actuate="onRequest"> ws:explicit</loc> annotation, in
            which case they can occur only where explicitly specified (see <specref ref="ExplicitWhitespaceHandling"/>).</termdef> Ignorable whitespace characters are not
          significant to the semantics of an expression. Whitespace is allowed before the first
          terminal and after the last terminal <phrase role="xquery">of a module</phrase>. Whitespace is allowed between any two <termref def="terminal">terminals</termref>. <nt def="doc-xquery40-Comment">Comments<!--$spec = xquery40--></nt> may also act as
          "whitespace" to prevent two adjacent terminals from being recognized as one. Some
          illustrative examples are as follows:</p>
                  <ulist>
                     <item>
                        <p>
                           <code nobreak="false">foo- foo</code> results in a syntax error. "foo-" would be recognized as a
              QName.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">foo -foo</code> is syntactically equivalent to <code role="parse-test" nobreak="false">foo - foo</code>, two QNames separated by a subtraction
              operator.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">foo(: This is a comment :)- foo</code> is syntactically
              equivalent to <code nobreak="false">foo - foo</code>. This is because the comment prevents the two
              adjacent terminals from being recognized as one.</p>
                     </item>
                     <item>
                        <p>
                           <code role="parse-test" nobreak="false">foo-foo</code> is syntactically equivalent to single QName.
              This is because "-" is a valid character in a QName. When used as an operator after
              the characters of a name, the "-" must be separated from the name, e.g. by using
              whitespace or parentheses.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">10div 3</code> results in a syntax error.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">10 div3</code> also results in a syntax error.</p>
                     </item>
                     <item>
                        <p>
                           <code nobreak="false">10div3</code> also results in a syntax error.</p>
                     </item>
                  </ulist>
               </div4>
               <div4 id="ExplicitWhitespaceHandling">
                  <head>Explicit Whitespace Handling</head>
                  <p>Explicit whitespace notation is specified with the EBNF productions, when it is different
          from the default rules, using the notation shown below. This notation is not inherited. In
          other words, if an EBNF rule is marked as /* ws: explicit */, the notation does not
          automatically apply to all the 'child' EBNF productions of that rule.</p>
                  <glist>
                     <gitem id="ws-explicit">
                        <label>ws: explicit</label>
                        <def>
                           <p>/* ws: explicit */ means that the EBNF notation explicitly notates, with
                  <code nobreak="false">S</code> or otherwise, where <termref def="Whitespace">whitespace
                  characters</termref> are allowed. In productions with the /* ws: explicit */
                  annotation, <specref ref="DefaultWhitespaceHandling"/> does not apply.
		  Comments are not allowed in these productions except where the <nt def="doc-xquery40-Comment">Comment<!--$spec = xquery40--></nt> non-terminal appears.
	      </p>
                        </def>
                     </gitem>
                  </glist>
                  <p role="xquery" id="ws-explicit-lex-states">For example, whitespace is not freely allowed
          by the direct constructor productions, but is specified explicitly in the grammar, in
          order to be more consistent with XML.</p>
               </div4>
            </div3>
         </div2>
         <div2 id="id-reserved-fn-names">
            <head>Reserved Function Names</head>
            <changes>
               <change issue="1208" PR="1212" date="2024-05-15">
          New keywords introducing item types, such as <code nobreak="false">record</code>, <code nobreak="false">item</code>, and <code nobreak="false">enum</code>,
            have been added to the list of reserved function names.
      </change>
            </changes>
            <p>The following names are not allowed as function names in an unprefixed form, because they
    can appear, followed by a left parenthesis, at the start of an XPath or XQuery expression that
    is not a function call.</p>
            <p>Names used in <nt def="doc-xquery40-TypeTest">NodeKindTests<!--$spec = xquery40--></nt>:</p>
            <slist>
               <sitem>attribute</sitem>
               <sitem>comment</sitem>
               <sitem>document-node</sitem>
               <sitem>element</sitem>
               <sitem>namespace-node</sitem>
               <sitem>node</sitem>
               <sitem>processing-instruction</sitem>
               <sitem>schema-attribute</sitem>
               <sitem>schema-element</sitem>
               <sitem>text</sitem>
            </slist>
            <p>Names used as syntactic keywords:</p>
            <slist>
               <sitem>array</sitem>
               <sitem>enum</sitem>
               <sitem>fn</sitem>
               <sitem>function</sitem>
               <sitem>gnode</sitem>
               <sitem>get</sitem>
               <sitem>if</sitem>
               <sitem>item</sitem>
               <sitem>jnode</sitem>
               <sitem>map</sitem>
               <sitem>record</sitem>
               <sitem>switch</sitem>
               <sitem>type</sitem>
               <sitem>typeswitch</sitem>
            </slist>
            <note>
               <p>As the language evolves in the future, it may become necessary to reserve additional
      names. Furthermore, use of common programming terms like <code nobreak="false">return</code> and
      <code nobreak="false">while</code> as function names may cause confusion even though they are not reserved. 
        The easiest way to avoid problems is to use an explicit namespace prefix in all calls 
        to user-defined functions.</p>
            </note>
         </div2>
         <div2 id="id-precedence-order">
            <head>Precedence Order (Non-Normative)</head>
            <p>The grammar in <specref ref="id-grammar"/> normatively defines built-in precedence among the
      operators of <phrase role="xquery">XQuery</phrase>. These operators are summarized here to make clear the order of their
      precedence from lowest to highest. The associativity column indicates the order in which
      operators of equal precedence in an expression are applied (further details below).</p>
            <table role="medium">
               <tbody>
                  <tr>
                     <th rowspan="1" colspan="1">#</th>
                     <th rowspan="1" colspan="1">Operator</th>
                     <th rowspan="1" colspan="1">Associativity</th>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">1</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-Expr">, (comma)<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">associative</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">2</td>
                     <td rowspan="1" colspan="1">
                        <phrase role="xquery">
                           <nt def="doc-xquery40-FLWORExpr">FLWOR<!--$spec = xquery40--></nt>,</phrase>
                        <nt def="doc-xquery40-QuantifiedExpr">some, every<!--$spec = xquery40--></nt>, <phrase role="xquery">
                           <nt def="doc-xquery40-SwitchExpr">switch<!--$spec = xquery40--></nt>,</phrase>
                        <phrase role="xquery">
                           <nt def="doc-xquery40-TypeswitchExpr">typeswitch<!--$spec = xquery40--></nt>,</phrase>
                        <phrase role="xquery">
                           <nt def="doc-xquery40-TryCatchExpr">try<!--$spec = xquery40--></nt>,</phrase>
                        <nt def="doc-xquery40-IfExpr">if<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">3</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-OrExpr">or<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">associative</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">4</td>
                     <td rowspan="1" colspan="1">
                        <nt def="prod-xquery40-AndExpr">and<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">associative</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">5</td>
                     <td rowspan="1" colspan="1">
                        <nt def="prod-xquery40-ValueComp">eq, ne, lt, le, gt, ge<!--$spec = xquery40--></nt>, <nt def="prod-xquery40-GeneralComp">=, !=, &lt;,
              &lt;=, &gt;, &gt;=<!--$spec = xquery40--></nt>, <nt def="prod-xquery40-NodeComp">is, is-not, &lt;&lt;, &gt;&gt;, precedes, follows, precedes-or-is, follows-or-is<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">6</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-OtherwiseExpr">otherwise<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">associative</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">7</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-StringConcatExpr">||<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">associative</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">8</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-RangeExpr">to<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">9</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-AdditiveExpr">+, - (binary)<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">left-to-right</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">10</td>
                     <td rowspan="1" colspan="1">
                        <nt def="prod-xquery40-MultiplicativeExpr">*, div, idiv, mod<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">left-to-right</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">11</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-UnionExpr">union, |<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">associative</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">12</td>
                     <td rowspan="1" colspan="1">
                        <nt def="prod-xquery40-IntersectExceptExpr">intersect, except<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">left-to-right</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">13</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-InstanceofExpr">instance of<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">14</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-TreatExpr">treat as<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">15</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-CastableExpr">castable as<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">16</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-CastExpr">cast as<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">17</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-ArrowExpr">=&gt;, =!&gt;<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">left-to-right</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">18</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-UnaryExpr">-, + (unary)<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">right-to-left</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">19</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-SimpleMapExpr">!<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">left-to-right</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">20</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-PathExpr">/, //<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">left-to-right</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">21</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-Predicate">a[b]<!--$spec = xquery40--></nt>, <nt def="doc-xquery40-FilterExprAM">a?[b]<!--$spec = xquery40--></nt>, <nt def="prod-xquery40-Lookup">a?b, a??b<!--$spec = xquery40--></nt>,
            <nt def="doc-xquery40-DynamicFunctionCall">a(b)<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">left-to-right</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">22</td>
                     <td rowspan="1" colspan="1">
                        <nt def="doc-xquery40-UnaryLookup">? (unary)<!--$spec = xquery40--></nt>
                     </td>
                     <td rowspan="1" colspan="1">NA</td>
                  </tr>
               </tbody>
            </table>
            <p>Entries in the <term>Associativity</term> column have the following meaning (where the symbol <code nobreak="false">⊙</code>
      represents any operator):</p>
            <ulist>
               <item>
                  <p>
                     <term>associative</term> means that the order of evaluation is immaterial: for example <code nobreak="false">a, b, c</code>
      can be evaluated either as <code nobreak="false">(a, b), c</code> or as <code nobreak="false">a, (b, c)</code>, producing the same
      result either way.</p>
               </item>
               <item>
                  <p>
                     <term>NA</term> indicates that it is not possible to write an expression of the form <code nobreak="false">a ⊙ b ⊙ c</code>
      for this particular operator: for example, the grammar does not allow <code nobreak="false">a = b = c</code>.</p>
               </item>
               <item>
                  <p>
                     <term>left-to-right</term> means that for expressions using these operators, 
      <code nobreak="false">a ⊙ b ⊙ c</code> is evaluated as <code nobreak="false">(a ⊙ b) ⊙ c</code>. As a special case, the operators <code nobreak="false">+</code>
      and <code nobreak="false">*</code> are associative provided they are not mixed with other operators of the same precedence.</p>
               </item>
               <item>
                  <p>
                     <term>right-to-left</term> is used only for unary operators, and indicates that <code nobreak="false">⊙ ⊙ a</code>
      is evaluated as <code nobreak="false">⊙ (⊙ a)</code>
                  </p>
               </item>
            </ulist>
            <p>These rules do not constrain the order in which the operands of an expression are evaluated (which might affect
    error behavior). See also <specref ref="errors"/>.</p>
            <note>
               <p>Parentheses can be used to override the operator precedence in the usual way. Square
        brackets in an expression such as <code nobreak="false">A[B]</code>
                  <code nobreak="false">A?[B]</code>or serve two roles: they act as an operator causing B to
        be evaluated once for each item in the value of A, and they act as parentheses enclosing the
        expression B.</p>
               <p role="xquery">Curly braces in an expression such as validate { E } or ordered { E } perform a
        similar bracketing role to the parentheses in a function call, but with the difference in
        most cases that E is an Expr rather than ExprSingle, meaning that it can use the comma
        operator.</p>
            </note>
         </div2>
      </div1>
      <div1 role="xquery" id="id-xq-context-components">
         <head>Context Components</head>
         <p>The tables in this section describe how values are assigned to
  the various components of the <termref def="dt-static-context"/> and <termref def="dt-dynamic-context"/>.</p>
         <div2 id="id-xq-static-context-components">
            <head>Static Context Components</head>
            <changes>
               <change issue="1343">
    Parts of the static context that were there purely to assist in static typing, such as the statically
    known documents, were no longer referenced and have therefore been dropped.
  </change>
            </changes>
            <p>The following table describes the components of the <term>static context</term>. The following aspects of each component are described:</p>
            <ulist>
               <item>
                  <p>
                     <emph>Default initial value:</emph> This is the
initial value of the component if it is not overridden or augmented by
the implementation or by a query.</p>
               </item>
               <item>
                  <p>
                     <emph>Can be
overwritten or augmented by implementation:</emph> Indicates whether
an XQuery implementation is allowed to replace the default initial
value of the component by a different, <termref def="dt-implementation-defined">implementation-defined</termref> value
and/or to augment the default initial value by additional <termref def="dt-implementation-defined">implementation-defined</termref>
values.</p>
               </item>
               <item>
                  <p>
                     <emph>Can be overwritten or augmented by prolog:</emph>
Indicates whether there are prolog declarations that can replace and/or augment
the initial value provided by default or by the implementation.
</p>
               </item>
               <item>
                  <p>
                     <emph>Can be overwritten or augmented by expressions:</emph>
Indicates whether there are expressions that can replace and/or augment
the value of the component for their subexpressions.
</p>
               </item>
               <item>
                  <p>
                     <emph>Consistency
Rules:</emph> Indicates rules that must be observed in assigning
values to the component. Additional consistency rules may be found in
<specref ref="id-consistency-constraints"/>.</p>
               </item>
            </ulist>
            <table width="100%" border="1" role="small">
               <caption>Static Context Components</caption>
               <tbody><!-- First group: can be overwritten/augmented by expressions -->
                  <tr>
                     <th rowspan="1" colspan="1">Component</th>
                     <th rowspan="1" colspan="1">Default initial value</th>
                     <th rowspan="1" colspan="1">Can be overwritten or augmented by implementation?</th>
                     <th rowspan="1" colspan="1">Can be overwritten or augmented by prolog?</th>
                     <th rowspan="1" colspan="1">Can be overwritten or augmented by expressions?</th>
                     <th rowspan="1" colspan="1">Consistency rules</th>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Statically known namespaces</td>
                     <td rowspan="1" colspan="1">See <specref ref="id-namespaces-and-qnames"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable and augmentable (except for <code nobreak="false">xml</code>)</td>
                     <td rowspan="1" colspan="1">overwriteable and augmentable by <specref ref="id-namespace-declaration"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable and augmentable by element constructor</td>
                     <td rowspan="1" colspan="1">Only one namespace can be assigned to a given prefix
per lexical scope.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Default element/type namespace</td>
                     <td rowspan="1" colspan="1">no namespace</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-default-namespace"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable by element constructor</td>
                     <td rowspan="1" colspan="1">Only one default namespace per lexical scope.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">In-scope variables</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">overwriteable and augmentable by <specref ref="id-variable-declarations"/> and  <specref ref="id-inline-func"/>, augmentable by <specref ref="id-module-import"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable and augmentable by variable-binding expressions</td>
                     <td rowspan="1" colspan="1">Only one definition per variable per lexical scope.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Context value static type</td>
                     <td rowspan="1" colspan="1">item()</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-context-value-declarations"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable by expressions that set the context value</td>
                     <td rowspan="1" colspan="1">None.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Ordering mode</td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">ordered</code>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-default-ordering-decl"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable by expression</td>
                     <td rowspan="1" colspan="1">Value must be <code nobreak="false">ordered</code> or <code nobreak="false">unordered</code>.</td>
                  </tr>
                  <!-- Second group: can be overwritten/augmented by (decls in) prologs,
     but not by expressions -->
                  <tr>
                     <td rowspan="1" colspan="1">Default function namespace</td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">fn</code>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable (not recommended)</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-default-namespace"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">In-scope schema types</td>
                     <td rowspan="1" colspan="1">built-in types in <code nobreak="false">xs</code>
                     </td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">augmentable by <specref ref="id-schema-import"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Only one definition per global or local type.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">In-scope element declarations</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">augmentable by  <specref ref="id-schema-import"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Only one definition per global or local element name.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">In-scope attribute declarations</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">augmentable by  <specref ref="id-schema-import"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Only one definition per global or local attribute name.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Statically known function signatures</td>
                     <td rowspan="1" colspan="1">the signatures of the <termref def="dt-system-function">system functions</termref>
                     </td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">augmentable by  <specref ref="id-module-import"/> and by  <specref ref="FunctionDeclns"/>; augmentable by  <specref ref="id-schema-import"/> (which adds constructor functions for user-defined types)</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Each function must have a unique <termref def="dt-expanded-qname">expanded QName</termref> and number of arguments.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Default collation</td>
                     <td rowspan="1" colspan="1">Unicode codepoint collation</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-default-collation-declaration"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Construction mode</td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">preserve</code>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-construction-declaration"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Value must be <code nobreak="false">preserve</code> or <code nobreak="false">strip</code>. </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Default order for empty sequences</td>
                     <td rowspan="1" colspan="1">implementation-defined</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-empty-order-decl"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Value must be <code nobreak="false">greatest</code> or <code nobreak="false">least</code>.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Boundary-space policy</td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">strip</code>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-boundary-space-decls"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Value must be <code nobreak="false">preserve</code> or <code nobreak="false">strip</code>. </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Copy-namespaces mode</td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">inherit, preserve</code>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-copy-namespaces-decl"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Value consists of <code nobreak="false">inherit</code> or <code nobreak="false">no-inherit</code>, and <code nobreak="false">preserve</code> or <code nobreak="false">no-preserve</code>.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Static Base URI</td>
                     <td rowspan="1" colspan="1">See rules in <specref ref="id-base-uri-decl"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by <specref ref="id-base-uri-decl"/>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Value must be a valid lexical representation of the type xs:anyURI.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Statically known decimal formats</td>
                     <td rowspan="1" colspan="1">the default (unnamed) decimal format, which has an implementation-dependent value</td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">augmentable, using <termref def="dt-decimal-format-decl">decimal format declarations</termref>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">each QName uniquely identifies a decimal format</td>
                  </tr>
                  <!-- Third group: cannot be overwritten/augmented by expressions or
     declarations in prologs -->
                  <tr>
                     <td rowspan="1" colspan="1">Statically known collations</td>
                     <td rowspan="1" colspan="1">only the default collation</td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Each URI uniquely identifies a collation.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">XPath 1.0 Compatibility Mode</td>
                     <td rowspan="1" colspan="1">
                        <code nobreak="false">false</code>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Must be <code nobreak="false">false</code>.</td>
                  </tr>
               </tbody>
            </table>
         </div2>
         <div2 id="id-xq-evaluation-context-components">
            <head>Dynamic Context Components</head>
            <p>The following table describes the components of the <term>dynamic context</term>. The following aspects of each component are described:</p>
            <ulist>
               <item>
                  <p>
                     <emph>Default initial value:</emph> This is the initial value of the component if it is not overridden or augmented by the implementation or by a query.</p>
               </item>
               <item>
                  <p>
                     <emph>Can be overwritten or augmented by implementation:</emph> Indicates whether an XQuery implementation is allowed to replace the default initial value of the component by a different <termref def="dt-implementation-defined">implementation-defined</termref> value and/or to augment the default initial value by additional <termref def="dt-implementation-defined">implementation-defined</termref> values.</p>
               </item>
               <item>
                  <p>
                     <emph>Can be overwritten or augmented by prolog:</emph>
Indicates whether there are prolog declarations that can replace and/or augment
the initial value provided by default or by the implementation.</p>
               </item>
               <item>
                  <p>
                     <emph>Can be overwritten or augmented by expressions:</emph>
Indicates whether there are expressions that can replace and/or augment
the value of the component for their subexpressions.</p>
               </item>
               <item>
                  <p>
                     <emph>Consistency Rules:</emph> Indicates rules that must be observed in assigning values to the component. Additional consistency rules may be found in <specref ref="id-consistency-constraints"/>.</p>
               </item>
            </ulist>
            <table width="100%" border="1" role="small">
               <caption>Dynamic Context Components</caption>
               <tbody>
                  <tr>
                     <th rowspan="1" colspan="1">Component</th>
                     <th rowspan="1" colspan="1">Default initial value</th>
                     <th rowspan="1" colspan="1">Can be overwritten or augmented by implementation?</th>
                     <th rowspan="1" colspan="1">Can be overwritten or augmented by prolog?</th>
                     <th rowspan="1" colspan="1">Can be overwritten or augmented by expressions?</th>
                     <th rowspan="1" colspan="1">Consistency rules</th>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Context value</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by a  <specref ref="id-context-value-declarations"/> in the main module
  </td>
                     <td rowspan="1" colspan="1">overwritten during evaluation of path expressions and predicates</td>
                     <td rowspan="1" colspan="1">Must be the same in the dynamic context of every module in a query.
  </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Context position</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by a  <specref ref="id-context-value-declarations"/> in the main module
  </td>
                     <td rowspan="1" colspan="1">overwritten during evaluation of path expressions and predicates</td>
                     <td rowspan="1" colspan="1">If context value is defined, context position must be &gt;0 and &lt;= context size; else  context position is <xtermref spec="DM31" ref="dt-absent"/>. </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Context size</td>
                     <td rowspan="1" colspan="1">none
  </td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">overwriteable by a  <specref ref="id-context-value-declarations"/> in the main module
      
  </td>
                     <td rowspan="1" colspan="1">overwritten during evaluation of path expressions and predicates</td>
                     <td rowspan="1" colspan="1">If context value is defined, context size must be &gt;0; else context size is <xtermref spec="DM31" ref="dt-absent"/>.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Variable values</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">overwriteable and augmentable by  <specref ref="id-variable-declarations"/>  and  <specref ref="id-inline-func"/>, augmentable by <specref ref="id-module-import"/>
                     </td>
                     <td rowspan="1" colspan="1">overwriteable and augmentable by variable-binding expressions</td>
                     <td rowspan="1" colspan="1">Names and values must be consistent with in-scope variables.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Named functions</td>
                     <td rowspan="1" colspan="1">the <termref def="dt-system-function">system functions</termref>
                     </td>
                     <td rowspan="1" colspan="1">augmentable</td>
                     <td rowspan="1" colspan="1">augmentable by 
 <specref ref="FunctionDeclns"/>, 
<specref ref="id-module-import"/>,
and
<specref ref="id-schema-import"/> ( (which adds constructor functions for user-defined types)</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Must be consistent with statically known function signatures</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Current dateTime</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">must be initialized <phrase role="xquery">by implementation</phrase>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Must include a timezone. Remains constant during evaluation of a query.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Implicit timezone</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">must be initialized <phrase role="xquery">by implementation</phrase>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">Remains constant during evaluation of a query.</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Available documents</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">must be initialized <phrase role="xquery">by implementation</phrase>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Available text resources</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">must be initialized <phrase role="xquery">by implementation</phrase>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Available collections</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">must be initialized <phrase role="xquery">by implementation</phrase>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Default collection</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Available URI collections</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">must be initialized <phrase role="xquery">by implementation</phrase>
                     </td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None</td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">Default URI collection</td>
                     <td rowspan="1" colspan="1">none</td>
                     <td rowspan="1" colspan="1">overwriteable</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">no</td>
                     <td rowspan="1" colspan="1">None</td>
                  </tr>
               </tbody>
            </table>
         </div2>
      </div1>
      <div1 id="id-impl-defined-items">
         <head>Implementation-Defined Items</head>
         <p>The following items in this specification 
  are <termref def="dt-implementation-defined">implementation-defined</termref>:</p>
         <olist>
            <item>
               <p>The version of Unicode that is used to construct expressions.</p>
            </item>
            <item>
               <p>The <termref def="dt-static-collations">statically-known collations</termref>.</p>
            </item>
            <item>
               <p>The <termref def="dt-timezone">implicit timezone</termref>.</p>
            </item>
            <item>
               <p>The circumstances in which <termref def="dt-warning">warnings</termref> are raised, and the ways in which warnings are handled.</p>
            </item>
            <item>
               <p>The method by which errors are reported to the external processing environment.</p>
            </item>
            <item>
               <p>Which version of XML and XML Names (e.g. <bibref ref="XML"/> and <bibref ref="XMLNAMES"/> or <bibref ref="XML1.1"/> and <bibref ref="XMLNAMES11"/>) and which version of XML Schema (e.g. <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/>) is used for the definitions of primitives such as characters and names, and for the definitions  of operations such as normalization of line endings and normalization of whitespace in attribute values. It is recommended that the latest applicable version be used (even if it is published later than this specification).</p>
            </item>
            <item>
               <p>How XDM instances are created from sources other than an Infoset or PSVI.</p>
            </item>
            <item role="xquery">
               <p>Any components of the <termref def="dt-static-context">static context</termref> 
  or <termref def="dt-dynamic-context">dynamic context</termref> that are overwritten or augmented 
  by the implementation.</p>
            </item>
            <item role="xquery">
               <p>The default handling of empty sequences returned by an ordering key (orderspec) 
  in an <code nobreak="false">order by</code> clause (<code nobreak="false">empty least</code> or <code nobreak="false">empty greatest</code>).</p>
            </item>
            <item role="xquery">
               <p>The names and semantics of any 
      <termref def="dt-extension-expression">extension expressions</termref> 
      (<termref def="dt-pragma">pragmas</termref>) recognized by the implementation.</p>
            </item>
            <item role="xquery">
               <p>The names and semantics of any 
      <termref def="dt-option-declaration">option declarations</termref> 
      recognized by the implementation.</p>
            </item>
            <item role="xquery">
               <p>Protocols (if any) by which parameters can be passed to an external function,
          and the result of the function can returned to the invoking query.</p>
            </item>
            <item role="xquery">
               <p>The process by which the specific modules to be imported by a
<termref def="dt-module-import">module import</termref> are identified 
      (includes processing of location hints, if any.)</p>
            </item>
            <item role="xquery">
               <p>The means by which serialization is invoked, if the <termref def="dt-serialization-feature">Serialization Feature</termref> is supported.</p>
            </item>
            <item role="xquery">
               <p>The default values for the <code nobreak="false">byte-order-mark</code>, <code nobreak="false">encoding</code>, <code nobreak="false">html-version</code>, <code nobreak="false">item-separator</code>, <code nobreak="false">media-type</code>, <code nobreak="false">normalization-form</code>, <code nobreak="false">omit-xml-declaration</code>, <code nobreak="false">standalone</code>, and <code nobreak="false">version</code> parameters, if the <termref def="dt-serialization-feature">Serialization Feature</termref> is supported.</p>
            </item>
            <item role="xquery">
               <p>The result of an unsuccessful call to an external function (for example,
if the function implementation cannot be found or does not return a value
of the declared type).</p>
            </item>
            <item role="xquery">
               <p>Limits on ranges of values for various data types, as enumerated in <specref ref="id-data-model-conformance"/>.</p>
            </item>
            <item role="xquery">
               <p>Syntactic extensions to XQuery, including both their syntax and semantics, as discussed in <specref ref="id-syntax-extensions"/>.</p>
            </item>
            <item>
               <p>Whether the type system is based on <bibref ref="XMLSchema10"/> or <bibref ref="XMLSchema11"/>. An implementation that has based its type system on XML Schema 1.0 is not required to support the use of the <code nobreak="false">xs:dateTimeStamp</code> constructor or the use of <code nobreak="false">xs:dateTimeStamp</code> or <code nobreak="false">xs:error</code> as <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt> in any expression.</p>
            </item>
            <item>
               <p>The signatures of functions provided by the implementation or via an implementation-defined API (see <specref ref="static_context"/>).</p>
            </item>
            <item>
               <p>Any <termref def="dt-environment-variables">environment variables</termref> provided by the implementation.</p>
            </item>
            <item>
               <p>Any rules used for static typing (see <specref ref="id-static-analysis"/>).</p>
            </item>
            <item>
               <p>Any serialization parameters provided by the implementation<phrase role="xquery"> (see  <specref ref="id-serialization"/>).</phrase>
               </p>
            </item>
            <item role="xquery">
               <p>The means by which the location hint for a serialization parameter document identifies the corresponding XDM instance (see  <specref ref="id-serialization"/>).</p>
            </item>
            <item>
               <p>What error, if any, is returned if an external function's implementation does not return the declared result type (see <specref ref="id-consistency-constraints"/>).</p>
            </item>
            <item role="xquery">
               <p>Any annotations defined by the implementation, and their associated behavior (see <specref ref="id-annotations"/>).</p>
            </item>
            <item role="xquery">
               <p>Any <termref def="dt-function-assertion">function assertions</termref> defined by the implementation.</p>
            </item>
            <item role="xquery">
               <p>The effect of function assertions understood by the implementation on <specref ref="id-assertions-subtype"/>.</p>
            </item>
            <item role="xquery">
               <p>Any implementation-defined variables defined by the implementation. (see <specref ref="id-variables"/>).</p>
            </item>
            <item role="xquery">
               <p>The ordering associated with <code nobreak="false">fn:unordered</code> in the implementation (see <specref ref="id-unordered-expressions"/>).</p>
            </item>
            <item role="xquery">
               <p>Any additional information provided for try/catch via the <code nobreak="false">err:additional</code> variable (see <specref ref="id-try-catch"/>).</p>
            </item>
            <item role="xquery">
               <p>The default boundary-space policy (see <specref ref="id-boundary-space-decls"/>).</p>
            </item>
            <item role="xquery">
               <p>The default collation (see <specref ref="id-default-collation-declaration"/>).</p>
            </item>
            <item role="xquery">
               <p>The default base URI (see <specref ref="id-base-uri-decl"/>).</p>
            </item>
         </olist>
         <note>
            <p>Additional <termref def="dt-implementation-defined">implementation-defined</termref> 
  items are listed in <bibref ref="xpath-datamodel-40"/> and <bibref ref="xpath-functions-40"/>.</p>
         </note>
      </div1>
      <div1 id="id-references">
         <head>References</head>
         <div2 id="id-normative-references">
            <head>Normative References</head>
            <blist>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="RFC2119"
                     key="RFC2119"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">S. Bradner.
      <emph>Key Words for use in RFCs to Indicate Requirement Levels.</emph> IETF RFC 2119.
      See <loc href="http://www.ietf.org/rfc/rfc2119.txt"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc2119.txt</loc>.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="RFC3986"
                     key="RFC3986"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">T. Berners-Lee, R. Fielding, and
      L. Masinter.  <emph>Uniform Resource Identifiers (URI): Generic
      Syntax</emph>. IETF RFC 3986.
      See <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="RFC3987"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">M. Duerst and M. Suignard.
      <emph>Internationalized Resource Identifiers (IRIs)</emph>.
      IETF RFC 3987. See <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="ISO10646"
                     key="ISO/IEC 10646"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">ISO (International Organization for Standardization).
      <emph>ISO/IEC 10646:2003. Information technology—Universal Multiple-Octet Coded Character Set (UCS)</emph>,
      as, from time to time, amended, replaced by a new edition, or expanded by the addition of new parts.
      [Geneva]: International Organization for Standardization.
      (See <loc href="http://www.iso.org"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.iso.org</loc> for the latest version.)</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="Unicode"
                     key="Unicode"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">The Unicode Consortium. <emph>The Unicode Standard.</emph>
      Reading, Mass.: Addison-Wesley, 2003, 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="dt-implementation-defined">implementation-defined</termref>,
      but implementations are recommended to use the latest Unicode version.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XML"
                     key="XML 1.0"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
      <emph>Extensible Markup Language (XML) 1.0.</emph>
      W3C Recommendation.
      See <loc href="http://www.w3.org/TR/REC-xml/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/REC-xml/</loc>.
      The edition of XML 1.0 must be no earlier than the Third Edition;
      the edition used is <termref def="dt-implementation-defined">implementation-defined</termref>,
      but we recommend that implementations use the latest version.
</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XML1.1"
                     key="XML 1.1"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
      <emph>Extensible Markup Language (XML) 1.1.</emph>
      W3C Recommendation.
      See <loc href="http://www.w3.org/TR/xml11/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xml11/</loc>
               </bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XMLBASE"
                     key="XML Base"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
      <emph>XML Base.</emph> W3C Recommendation. See
      <loc href="http://www.w3.org/TR/xmlbase/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xmlbase/</loc>
               </bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XMLNAMES"
                     key="XML Names"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
      <emph>Namespaces in XML.</emph> W3C Recommendation. See
      <loc href="http://www.w3.org/TR/REC-xml-names/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/REC-xml-names/</loc>
               </bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XMLNAMES11"
                     key="XML Names 1.1"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
      <emph>Namespaces in XML 1.1.</emph> W3C Recommendation. See
      <loc href="http://www.w3.org/TR/xml-names11/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xml-names11/</loc>
               </bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XMLID"
                     key="XML ID"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium. <emph>xml:id Version 1.0.</emph>
      W3C Recommendation. See <loc href="http://www.w3.org/TR/xml-id/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xml-id/</loc>
               </bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XMLSchema10"
                     key="XML Schema 1.0"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
      <emph>XML Schema, Parts 0, 1, and 2 (Second Edition)</emph>. W3C Recommendation, 28 October 2004.
      See <loc href="http://www.w3.org/TR/xmlschema-0/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xmlschema-0/</loc>,
      <loc href="http://www.w3.org/TR/xmlschema-1/"
                       id="schema1"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xmlschema-1/</loc>,
      and <loc href="http://www.w3.org/TR/xmlschema-2/"
                       id="schema2"
                       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"
                     key="XML Schema 1.1"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
      <emph>XML Schema, Parts 1, and 2</emph>. W3C Recommendation 5 April 2012.
      See <loc href="http://www.w3.org/TR/xmlschema11-1/"
                       id="schema1-11"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xmlschema11-1/</loc>,
      and <loc href="http://www.w3.org/TR/xmlschema11-2/"
                       id="schema2-11"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xmlschema11-2/</loc>.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xpath-datamodel-40"
                     key="XDM 4.0"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xpath-functions-40"
                     key="Functions and Operators 4.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"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xslt-xquery-serialization-40"
                     key="Serialization 4.0"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <!--<bibl id="xquery-update-30" key="XQuery Update Facility 3.0" role="xquery"/>-->
            </blist>
         </div2>
         <div2 id="id-non-normative-references">
            <head>Non-normative References</head>
            <blist>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xquery-30-requirements"
                     key="XQuery 3.0 Requirements"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xquery-31-requirements"
                     key="XQuery 3.1 Requirements"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xquery-30"
                     key="XQuery 3.0"
                     role="xquery"
                     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 id="xqueryx-31" key="XQueryX 3.1" role="xquery"/>-->
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xslt-40"
                     key="XSLT 4.0"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="DOM"
                     key="Document Object Model"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium. <emph>Document Object Model (DOM) Level 3 Core Specification.</emph> W3C Recommendation, April 7, 2004. See <loc href="http://www.w3.org/TR/DOM-Level-3-Core/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/DOM-Level-3-Core/</loc>.</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"
                     key="XPath 1.0"
                     id="xpath"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="XPath 2.0"
                     id="xpath20"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="XPath 3.0"
                     id="xpath-30"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="XPath 3.1"
                     id="xpath-31"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest"/>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XPTR"
                     key="XPointer"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium. <emph>XML
Pointer Language (XPointer).</emph> W3C Last Call Working Draft 8 January 2001.
See <loc href="http://www.w3.org/TR/WD-xptr"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/WD-xptr</loc>
               </bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="UseCases"
                     key="XML Query Use Cases"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide
Web Consortium. <emph>XML Query Use Cases</emph>. W3C Working Draft, 8 June 2006.
See <loc href="http://www.w3.org/TR/xquery-use-cases/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xquery-use-cases/</loc>.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xml11schema10"
                     key="XML 1.1 and Schema 1.0"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide
Web Consortium. <emph>Processing XML 1.1 Documents with XML Schema 1.0 Processors</emph>.
W3C Working Group Note, 11 May 2005.
See <loc href="http://www.w3.org/TR/xml11schema10/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/xml11schema10/</loc>.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="RFC1738"
                     key="Uniform Resource Locators (URL)"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">Internet Engineering Task Force (IETF).
<emph>Uniform Resource Locators (URL)</emph>. Request For Comment No. 1738, Dec. 1994.
See <loc href="http://www.ietf.org/rfc/rfc1738.txt"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc1738.txt</loc>.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="ODMG"
                     id="ODMG"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">Rick Cattell et al. <emph>The
Object Database Standard: ODMG-93, Release 1.2</emph>. Morgan Kaufmann
Publishers, San Francisco, 1996.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="Quilt"
                     id="Quilt"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">Don Chamberlin,
Jonathan Robie, and Daniela Florescu. <emph>Quilt: an XML Query Language for
Heterogeneous Data Sources</emph>.  In <emph>Lecture Notes in Computer
Science</emph>, Springer-Verlag, Dec. 2000.  
<!--
Also available at <loc href="http://www.almaden.ibm.com/cs/people/chamberlin/quilt_lncs.pdf">http://www.almaden.ibm.com/cs/people/chamberlin/quilt_lncs.pdf</loc>.
See also <loc href="http://www.almaden.ibm.com/cs/people/chamberlin/quilt.html">http://www.almaden.ibm.com/cs/people/chamberlin/quilt.html</loc>.
-->
</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="XML-QL"
                     id="XML-QL"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">Alin Deutsch, Mary Fernandez,
Daniela Florescu, Alon Levy, and Dan Suciu.
<emph>A Query Language for XML</emph>.
</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="SQL"
                     id="SQL"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">International Organization for
Standardization (ISO).  <emph>Information Technology — Database Language
SQL</emph>. Standard No. ISO/IEC 9075:2011.  (Available from American
National Standards Institute, New York, NY 10036, (212)
642-4900.)</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     key="XQL"
                     id="XQL"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">J. Robie, J. Lapp, D. Schach. <emph>XML
Query Language (XQL)</emph>. See <loc href="http://www.w3.org/TandS/QL/QL98/pp/xql.html"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TandS/QL/QL98/pp/xql.html</loc>.</bibl>
            </blist>
         </div2>
         <div2 id="id-background-material">
            <head>Background Material</head>
            <blist>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="CHARMOD"
                     key="Character Model"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">World Wide Web Consortium.
<emph>Character Model for the World Wide Web.</emph> W3C Working
Draft. See <loc href="http://www.w3.org/TR/charmod/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/TR/charmod/</loc>.</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="xslt"
                     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="UseCaseQueries"
                     key="Use Case Sample Queries"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">Queries
from the XQuery 1.0 Use Cases, presented in a single file.
See
<loc href="http://www.w3.org/2010/12/xquery-30-use-cases/xquery-30-use-case-queries.txt"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/2010/12/xquery-30-use-cases/xquery-30-use-case-queries.txt</loc>.
</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="XQueryQueries"
                     key="XQuery Sample Queries"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">Queries
from this document, presented in a single file.
See
<loc href="http://www.w3.org/2013/01/xquery-30-use-cases/xquery-30-example-queries.txt"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://www.w3.org/2013/01/xquery-30-use-cases/xquery-30-example-queries.txt</loc>.
</bibl>
               <bibl xmlns:xlink="http://www.w3.org/1999/xlink"
                     id="Moustache"
                     key="Moustache"
                     role="xquery"
                     xlink:type="simple"
                     xlink:show="replace"
                     xlink:actuate="onRequest">
                  <emph>mustache</emph> - Logic-less templates. See
<loc href="http://mustache.github.io/mustache.5.html"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">http://mustache.github.io/mustache.5.html</loc>.
</bibl>
            </blist>
         </div2>
      </div1>
      <div1 id="id-errors">
         <head>Error Conditions</head>
         <note>
            <p>Historically, codes starting "XP" were for XPath errors, "XQ" for XQuery errors.
   This was followed by "ST" for static errors, "TY" for type errors, or "DY" for dynamic
   errors. Over time, some errors have been reclassified, but the error codes
   have been retained for compatibility reasons. Applications should therefore attach no
   significance to the choice of codes.</p>
         </note>
         <error-list>
            <error spec="XP" code="0001" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if analysis of an
            expression relies on some component of the <termref def="dt-static-context">static
               context</termref> that <phrase diff="del">has not been assigned a
               value</phrase>
                  <phrase diff="add">is <xtermref spec="DM40" ref="dt-absent"/>
                  </phrase>.</p>
            </error>
            <error spec="XP" code="0002" class="DY" type="type">
               <p>It is a <termref def="dt-type-error">type error</termref> if evaluation of an
            expression relies on some part of the <termref def="dt-dynamic-context">dynamic
               context</termref> that is <xtermref spec="DM40" ref="dt-absent"/>.</p>
               <note>
                  <p>In version 4.0 this has been reclassified as a type error rather than
         a dynamic error. This change allows a processor to report the error during static
         analysis where possible; for example if the body of a user-defined
         function is written as <code nobreak="false">fn($x) { @code }</code>.
         The error code is prefixed <code nobreak="false">XPDY</code> rather than <code nobreak="false">XPTY</code>
         for backwards compatibility reasons.</p>
               </note>
            </error>
            <error spec="XP" code="0003" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if an expression is not a
            valid instance of the grammar defined in <specref ref="id-grammar"/>.</p>
            </error>
            <error spec="XP" code="0004" class="TY" type="type">
               <p>It is a <termref def="dt-type-error">type error</termref> if, during the <termref def="dt-static-analysis">static analysis phase</termref>, an expression is found to
            have a <termref def="dt-static-type">static type</termref> that is not appropriate for
            the context in which the expression occurs, or during the <termref def="dt-dynamic-evaluation">dynamic evaluation phase</termref>, the <termref def="dt-dynamic-type">dynamic type</termref> of a value does not match a required
            type as specified by the matching rules in <specref ref="id-sequencetype-matching"/>.</p>
            </error>
            <!--<error spec="XP" code="0005" class="ST" type="static">
         <p> During the analysis phase, it is a <termref def="dt-static-error">static
               error</termref> if the <termref def="dt-static-type">static type</termref> assigned
            to an expression other than the expression <code>()</code> or <code>data(())</code> is
               <code>empty-sequence()</code>.</p>
      </error>-->
            <error spec="XP" code="0006" class="TY" type="type">
               <p>During the analysis phase, an expression is classified as <termref def="dt-implausible"/>
            if the inferred <termref def="dt-static-type">static type</termref>
                  <var>S</var> and
            the required type <var>R</var> are substantively disjoint; more specifically, if neither
            of the types is a subtype of the other, and if the only values
            that are instances of both types are one or more of: the empty sequence, the empty map, 
            and the empty array.</p>
            </error>
            <error spec="XP" code="0008" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if an expression refers
            to an element name, attribute name, schema type name, or variable name
            that is not defined in the <termref def="dt-static-context">static context</termref>,
            except for an ElementName in an <nt def="doc-xquery40-ElementNodeType"><!--$spec = xquery40--></nt> or an
            AttributeName in an <nt def="doc-xquery40-AttributeNodeType"><!--$spec = xquery40--></nt>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0009"
                   class="ST"
                   type="static">
               <p diff="chg"> An implementation that does not support the Schema Aware Feature must raise
            a <termref def="dt-static-error">static error</termref> if a Prolog contains a schema
            import.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0012"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the set of definitions
            contained in all schemas imported by a Prolog do not satisfy the conditions for schema
            validity specified in Sections 3 and 5 of Part 1 of <bibref ref="XMLSchema10"/> or
               <bibref ref="XMLSchema11"/>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0013"
                   class="ST"
                   type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> if an implementation
            recognizes a pragma but determines that its content is invalid.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0014" class="ST" type="static">
<p>(Not currently used.)</p>
</error>
-->
            <!--
<error spec="XQ" role="xquery" code="0015" class="ST" type="static">
<p>(Not currently used.)</p>
</error>
-->
            <!--<error spec="XQ" role="xquery" code="0016" class="ST" type="static">
         <p>An implementation that does not support the Module Feature raises a <termref
               def="dt-static-error">static error</termref> if it encounters a <termref
               def="dt-module-declaration">module declaration</termref> or a <termref
               def="dt-module-import">module import</termref>.</p>
      </error>-->
            <error spec="XP" code="0017" class="ST" type="static">
               <p>It is a <termref def="dt-static-error"/> if the <termref def="dt-expanded-qname"/>
            and number of arguments in a static function call do not match the name and
            <termref def="dt-arity-range"/> of a <termref def="dt-function-definition"/> in the
            <termref def="dt-static-context"/>, or if an argument keyword in the function call
            does not match a parameter name in that function definition, or if two arguments
            in the function call bind to the same parameter in the function definition.</p>
            </error>
            <error spec="XP" code="0018" class="TY" type="type">
               <p>It is a <termref def="dt-type-error">type error</termref> if the result of a path
            operator contains both nodes and non-nodes.</p>
            </error>
            <error spec="XP" code="0019" class="TY" type="type">
               <p> It is a <termref def="dt-type-error">type error</termref> if <code nobreak="false">E1</code> in a path
            expression <code nobreak="false">E1/E2</code> does not evaluate to a sequence of nodes.</p>
            </error>
            <error spec="XP" code="0020" class="TY" type="type">
               <p> It is a <termref def="dt-type-error">type error</termref> if, in an axis step, the
            context item is not a node.</p>
            </error>
            <error spec="XP" code="0021" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if two fields in a record declaration
            have the same name.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0022"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if <phrase diff="del">the
               value of</phrase> a <termref def="dt-namespace-decl-attr">namespace declaration
               attribute</termref>
                  <phrase diff="del">is not a <nt def="prod-xquery40-URILiteral">URILiteral<!--$spec = xquery40--></nt>.</phrase>
                  <phrase diff="add">contains an <nt def="doc-xquery40-EnclosedExpr">EnclosedExpr<!--$spec = xquery40--></nt>.</phrase>
               </p>
            </error>
            <error spec="XP" code="0023" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if a recursive record type
            cannot be instantiated (typically because it contains a self-reference that is neither optional
            nor emptiable). Processors are not required to detect this error.</p>
            </error>
            <error spec="XQ" code="0024" class="TY" type="type">
               <p> It is a <termref def="dt-type-error">type error</termref> if the content sequence in an
            element constructor contains an attribute node following a node that is not an attribute
            node.</p>
            </error>
            <error spec="XQ" code="0025" class="DY" type="dynamic">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if any attribute of a
            constructed element does not have a name that is distinct from the names of all other
            attributes of the constructed element.</p>
            </error>
            <error spec="XQ" code="0026" class="DY" type="dynamic">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if the result of the
            content expression of a computed processing instruction constructor contains the string
               <code nobreak="false">"?&gt;"</code>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0027"
                   class="DY"
                   type="dynamic">
               <p> In a validate expression, it is a <termref def="dt-dynamic-error">dynamic
               error</termref> if the root element information item in the PSVI resulting from
            validation does not have the expected validity property: <code nobreak="false">valid</code> if
            validation mode is <code nobreak="false">strict</code>, or either <code nobreak="false">valid</code> or
               <code nobreak="false">notKnown</code> if validation mode is <code nobreak="false">lax</code>.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0028" class="TY" type="type">
<p>
(Not currently used.)</p>
</error>
-->
            <!--
<error spec="XQ" code="0029" class="DY" type="dynamic" role="xquery">
<p>(Not currently used.)</p>
</error>
-->
            <error spec="XQ" role="xquery" code="0030" class="TY" type="type">
               <p> It is a <termref def="dt-type-error">type error</termref> if the argument of a
               <code nobreak="false">validate</code> expression does not evaluate to exactly one document or element
            node. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0031"
                   class="ST"
                   type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> if the version number
            specified in a version declaration is not supported by the implementation. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0032"
                   class="ST"
                   type="static">
               <p>A <termref def="dt-static-error">static error</termref> is raised if a Prolog contains
            more than one <termref def="dt-base-uri-decl">base URI declaration</termref>.</p>
            </error>
            <error spec="XQ" code="0033" class="ST" type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> if a module contains
            multiple bindings for the same namespace prefix.</p>
            </error>
            <error spec="XQ"
                   code="0034"
                   class="ST"
                   type="static"
                   role="xquery"
                   diff="chg"
                   at="B">
               <p>It is a <termref def="dt-static-error">static error</termref> if multiple functions
            declared <phrase role="xquery">or imported by a <termref def="dt-module">module</termref>
                  </phrase> have the same <termref def="dt-expanded-qname">expanded QName</termref>
            and overlapping arity ranges (the arity range of a function declaration is <var>M</var> to <var>M+N</var>,
            where <var>M</var> is the number of required parameters and <var>N</var> is the number of 
            optional parameters).</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0035"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> to import two schema
            components that both define the same name in the same symbol space and in the same
            scope. </p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0036" class="ST" type="type">
          <p diff="add">(Not currently used.)</p>
          <p diff="del">
            It is a <termref def="dt-static-error">static error</termref>
            to import a module if the
            <termref def="dt-issd">in-scope schema definitions</termref>
            of the importing module do not include all of the following:
          </p>
          <olist diff="del">
             <item>
                <p>An <termref def="dt-is-types">in-scope schema type</termref>
                   for each type name that appears:
                </p>
                <olist>
                   <item>
                      <p>in the type of a variable that is declared in the imported module
                         and referenced in the importing module, OR
                      </p>
                   </item><item>
                      <p>in a parameter-type or result-type of a function that is declared
                         in the imported module and referenced in the importing module.
                      </p>
                   </item>
                </olist>
             </item><item>
                <p>An <termref def="dt-is-elems">in-scope element declaration</termref>
                   for each element-name <code>EN</code> such that:
                </p>
                <olist>
                   <item>
                      <p><code>schema-element(EN)</code> appears in the declared
                         type of a variable
                         in the imported module, and that variable is referenced
                         in the importing module, OR
                      </p>
                   </item><item>
                      <p><code>schema-element(EN)</code> appears in a parameter-type or
                         result-type of a function declared in the imported module, and
                         that function is referenced in the importing module.
                      </p>
                   </item>
                </olist>
             </item><item>
                <p>An <termref def="dt-is-attrs">in-scope attribute declaration</termref>
                   for each attribute-name <code>AN</code> such that:
                </p>
                <olist>
                   <item>
                      <p><code>schema-attribute(AN)</code> appears in the declared
                         type of a variable
                         in the imported module, and that variable is referenced
                         in the importing module, OR
                      </p>
                   </item><item>
                      <p><code>schema-attribute(AN)</code> appears in a parameter-type
                         or result-type
                         of a function declared in the imported module, and that function
                         is referenced in the importing module.
                      </p>
                   </item>
                </olist>
             </item>
          </olist>
</error>
-->
            <!--
<error spec="XQ" role="xquery" code="0037" class="ST" type="static">
<p>(Not currently used.)</p>
</error>
-->
            <error spec="XQ"
                   role="xquery"
                   code="0038"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if a Prolog contains more
            than one <termref def="dt-default-collation-decl">default collation
               declaration</termref>, or the value specified by a default collation declaration is
            not present in <termref def="dt-static-collations">statically known
            collations</termref>.</p>
            </error>
            <error spec="XQ" code="0039" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> for <phrase role="xquery">a function declaration or</phrase>
                  <phrase diff="add">an inline function expression</phrase> to have more than one
            parameter with the same name. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0040"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the attributes
            specified by a direct element constructor do not have distinct <termref def="dt-expanded-qname">expanded QNames</termref>.</p>
            </error>
            <error spec="XQ" code="0041" class="DY" type="dynamic">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if the value of the
            name expression in a computed processing instruction constructor cannot be cast to the
            type <code nobreak="false">xs:NCName</code>.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0042" class="ST" type="static">
<p>
(Not currently used.)</p>
</error>
-->
            <!--
<error spec="XQ" role="xquery" code="0043" class="ST" type="static">
<p>
(Not currently used.)</p>
</error>
-->
            <error spec="XQ" code="0044" class="DY" type="dynamic"><!-- <change diff="chg" at="XQ.E19"> -->
               <p>It is a <termref def="dt-dynamic-error">dynamic error</termref> the node-name of a node
            constructed by a computed attribute constructor has any of the following properties: </p>
               <ulist>
                  <item>
                     <p>Its namespace prefix is <code nobreak="false">xmlns</code>. </p>
                  </item>
                  <item>
                     <p>It has no namespace prefix and its local name is <code nobreak="false">xmlns</code>. </p>
                  </item>
                  <item>
                     <p>Its namespace URI is <code nobreak="false">http://www.w3.org/2000/xmlns/</code>. </p>
                  </item>
                  <item>
                     <p>Its namespace prefix is <code nobreak="false">xml</code> and its namespace URI is not
                     <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>. </p>
                  </item>
                  <item>
                     <p>Its namespace prefix is other than <code nobreak="false">xml</code> and its namespace URI is
                     <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>. </p>
                  </item>
               </ulist>
               <!-- </change> -->
            </error>
            <error spec="XQ"
                   code="0045"
                   class="ST"
                   type="static"
                   role="xquery">
               <p> It is a <termref def="dt-static-error">static error</termref> if <phrase diff="chg">the
               name of <phrase diff="add" at="bug29170">a variable annotation,</phrase> a function annotation, or</phrase> the function name in a function declaration
            is  <phrase diff="chg" at="bug29170">in a <termref def="dt-reserved-namespaces">reserved namespace</termref>.</phrase>
               </p>
            </error>
            <error spec="XQ" code="0046" class="ST" type="static">
               <p>An implementation <phrase role="xquery">
                     <termref def="may">MAY</termref>
                  </phrase> raise a <termref def="dt-static-error">static
               error</termref> if the value of <phrase role="xquery">a <nt def="prod-xquery40-URILiteral">URILiteral<!--$spec = xquery40--></nt> or </phrase>a <nt def="prod-xquery40-BracedURILiteral">BracedURILiteral<!--$spec = xquery40--></nt> is
            of nonzero length and is <phrase diff="del">not in the lexical space of
                  <code nobreak="false">xs:anyURI</code>
                  </phrase>
                  <phrase diff="add">neither an absolute URI nor a
               relative URI</phrase>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0047"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if multiple module
            imports in the same <nt def="prod-xquery40-Prolog"><!--$spec = xquery40--></nt> specify the same target namespace.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0048"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error"/> if a function, variable,
            or item type declared in a <termref def="dt-library-module"/> is not 
            in the <termref def="dt-target-namespace"/> of the library module.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0049"
                   class="ST"
                   type="static">
               <p>It is a <termref def="dt-static-error"/> if two or more variables
            declared or imported by a <termref def="dt-module"/> have equal <termref def="dt-expanded-qname">expanded QNames</termref> (as defined by the <code nobreak="false">eq</code>
            operator.)</p>
            </error>
            <error spec="XP" code="0050" class="DY" type="type">
               <p>It is a <termref def="dt-type-error"/> if the <termref def="dt-dynamic-type"/> of the operand of a <code nobreak="false">treat</code>
            expression does not match the <termref def="dt-sequence-type"/>
            designated by the <code nobreak="false">treat</code> expression.</p>
               <note>
                  <p>This error might also be raised by a
            path expression beginning with <code nobreak="false">/</code> or <code nobreak="false">//</code> if the context node
            is not in a tree that is rooted at a document node. This is because a leading
               <code nobreak="false">/</code> or <code nobreak="false">//</code> in a path expression is an abbreviation for an
            initial step that includes the clause <code nobreak="false">treat as document-node()</code>.</p>
               </note>
            </error>
            <error spec="XP" code="0051" class="ST" type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> if an <termref def="dt-expanded-qname"/> used as an <nt def="doc-xquery40-ItemType">ItemType<!--$spec = xquery40--></nt>
               in a <nt def="doc-xquery40-SequenceType"><!--$spec = xquery40--></nt> is not defined
            in the <termref def="dt-static-context"/> either as a <termref def="dt-named-item-type"/>
            in the <termref def="dt-in-scope-named-item-types"/>,
            or as a <termref def="dt-generalized-atomic-type"/>
            in the <termref def="dt-is-types"/>.</p>
            </error>
            <error spec="XQ" code="0052" class="ST" type="static">
               <p>The type named in a cast or castable expression must be the name of a type defined in the <termref def="dt-is-types">in-scope
               schema types</termref>, and the<phrase diff="del" at="2015-07-07">
                     <code nobreak="false">{variety}</code> of the</phrase> type must be
               <code nobreak="false">simple</code>.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0053" class="ST" type="static">
<p>
(Not currently used.)</p>
</error>
-->
            <error spec="XQ"
                   role="xquery"
                   code="0054"
                   class="DY"
                   type="dynamic">
               <p>It is a <termref def="dt-dynamic-error">dynamic error</termref> if a cycle is
            encountered in the definition of a module’s dynamic context components, for example
            because of a cycle in variable declarations.</p>
            </error>
            <error spec="XQ"
                   code="0055"
                   class="ST"
                   type="static"
                   role="xquery">
               <p>It is a <termref def="dt-static-error">static error</termref> if a Prolog contains more
            than one <termref def="dt-copy-namespaces-decl">copy-namespaces
            declaration</termref>.</p>
            </error>
            <!--
<error spec="XQ" code="0056" class="ST" type="static" role="xquery">
<p>
(Not currently used.)</p>
</error>
-->
            <error spec="XQ"
                   code="0057"
                   class="ST"
                   type="static"
                   role="xquery">
               <p> It is a <termref def="dt-static-error">static error</termref> if a schema import binds
            a namespace prefix but does not specify a target namespace other than a zero-length
            string.</p>
            </error>
            <error spec="XQ"
                   code="0058"
                   class="ST"
                   type="static"
                   role="xquery">
               <p> It is a <termref def="dt-static-error">static error</termref> if multiple schema
            imports specify the same target namespace.</p>
            </error>
            <error spec="XQ"
                   code="0059"
                   class="ST"
                   type="static"
                   role="xquery">
               <p> It is a <termref def="dt-static-error">static error</termref> if an implementation is
            unable to process a schema or module import by finding a schema or module with the
            specified target namespace.</p>
            </error>
            <!--<error spec="XQ" code="0060" class="ST" type="static" role="xquery">
         <p> It is a <termref def="dt-static-error">static error</termref> if the name of a function
            in a function declaration is not in a namespace (<termref def="dt-expanded-qname"
               >expanded QName</termref> has a null namespace URI).</p>
      </error>-->
            <error spec="XQ"
                   role="xquery"
                   code="0061"
                   class="DY"
                   type="dynamic">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if the operand of a
            validate expression is a document node whose children do not consist of exactly one
            element node and zero or more comment and processing instruction nodes, in any
            order.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0062" class="DY" type="dynamic">
<p>(Not currently used.)</p>
</error>
-->
            <!--
<error spec="XQ" code="0063" class="ST" type="static" role="xquery">
<p>
(Not currently used.)</p>
</error>
-->
            <error spec="XQ" code="0064" class="DY" type="dynamic">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if the value of the
            name expression in a computed processing instruction constructor is equal to
            <code nobreak="false">XML</code> (in any combination of upper and lower case).</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0065"
                   class="ST"
                   type="static">
               <p>A <termref def="dt-static-error">static error</termref> is raised if a Prolog contains
            more than one ordering mode declaration.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0066"
                   class="ST"
                   type="static">
               <p>A <termref def="dt-static-error">static error</termref> is raised if a Prolog contains
            more than one default element/type namespace declaration, or more than one default
            function namespace declaration. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0067"
                   class="ST"
                   type="static">
               <p>A <termref def="dt-static-error">static error</termref> is raised if a Prolog contains
            more than one <termref def="dt-construction-decl">construction
            declaration</termref>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0068"
                   class="ST"
                   type="static">
               <p>A <termref def="dt-static-error">static error</termref> is raised if a Prolog contains
            more than one <termref def="dt-boundary-space-decl">boundary-space
            declaration</termref>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0069"
                   class="ST"
                   type="static">
               <p>A <termref def="dt-static-error">static error</termref> is raised if a Prolog contains
            more than one <termref def="dt-empty-order-decl">empty order declaration</termref>.</p>
            </error>
            <error spec="XQ" code="0070" class="ST" type="static" diff="chg">
               <p>A namespace declaration must not define a binding for the prefix <code nobreak="false">xml</code>
         or <code nobreak="false">xmlns</code>, nor for the URI <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>
         or <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.</p>
               <p role="xquery">The same rule applies to namespace declaration attributes
         (see <specref ref="id-namespaces"/>), except that in this case it is permitted to provide
         a redundant namespace declaration attribute in the form 
            <code nobreak="false">xmlns:xml="http://www.w3.org/XML/1998/namespace"</code>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0071"
                   class="ST"
                   type="static">
               <p>A <termref def="dt-static-error">static error</termref> is raised if the namespace
            declaration attributes of a direct element constructor do not have distinct names.</p>
            </error>
            <error spec="XQ" code="0072" class="DY" type="dynamic">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if the result of the
            content expression of a computed comment constructor contains two adjacent hyphens or
            ends with a hyphen.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0073" class="ST" type="static">
<p diff="chg" at="XQ.E8">(Not currently used.)</p>
</error>
-->
            <error spec="XQ" code="0074" class="DY" type="dynamic">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if the value of the
            name expression in a computed element or attribute constructor cannot be converted to an
               <termref def="dt-expanded-qname">expanded QName</termref> (for example, because it
            contains a namespace prefix not found in <termref def="dt-static-namespaces">statically
               known namespaces</termref>.)</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0075"
                   class="ST"
                   type="static">
               <p> An implementation that does not support the <phrase diff="add" at="2015-07-04">Schema Aware Feature</phrase>
                  <phrase diff="del" at="2015-07-04">Validation Feature</phrase> must raise a <termref def="dt-static-error">static error</termref> if it encounters a <code nobreak="false">validate</code>
            expression.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0076"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if a
               <code nobreak="false">collation</code> subclause in an <code nobreak="false">order by</code>
                  <phrase diff="add" at="2015-07-07">or <code nobreak="false">group by</code>
                  </phrase> clause of a FLWOR
            expression does not identify a collation that is present in <termref def="dt-static-collations">statically known collations</termref>.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0077" class="ST" type="static">
<p>
(Not currently used.)</p>
</error>
-->
            <!--
<error spec="XQ" role="xquery" code="0078" class="ST" type="static">
<p>
(Not currently used.)</p>
</error>
-->
            <error spec="XQ"
                   role="xquery"
                   code="0079"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if an extension
            expression contains neither a <termref def="dt-pragma">pragma</termref> that is
            recognized by the implementation nor an expression enclosed in curly braces.</p>
            </error>
            <error spec="XP" code="0080" class="ST" type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> if the target type of a
               <code nobreak="false">cast</code> or <code nobreak="false">castable</code> expression is
               <code nobreak="false">xs:NOTATION</code>, <phrase diff="add">
                     <code nobreak="false">xs:anySimpleType</code>,</phrase> or
               <code nobreak="false">xs:anyAtomicType</code>.</p>
            </error>
            <error spec="XP" code="0081" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if a QName used in
               <phrase role="xquery">a query</phrase>
            contains a namespace prefix that cannot be expanded into a namespace URI by using the
               <termref def="dt-static-namespaces">statically known namespaces</termref>.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0082" class="ST" type="static">
<p>(Not currently used.)</p>
</error>
-->
            <!--
<error spec="XP" code="0083" class="ST" type="static">
<p>
(Not currently used.)</p>
</error>
-->
            <error spec="XQ"
                   code="0084"
                   class="DY"
                   type="dynamic"
                   role="xquery">
               <p> It is a <termref def="dt-dynamic-error">dynamic error</termref> if the element
            validated by a <code nobreak="false">validate</code> statement does not have a top-level element
            declaration in the <termref def="dt-is-elems">in-scope element declarations</termref>,
            if validation mode is <code nobreak="false">strict</code>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0085"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the namespace URI in a
            namespace declaration attribute is a zero-length string, and the implementation does not
            support <bibref ref="XMLNAMES11"/>.</p>
            </error>
            <error spec="XQ" code="0086" class="TY" type="type">
               <p> It is a <termref def="dt-type-error">type error</termref> if the typed value of a
            copied <phrase role="xquery">element or</phrase> attribute node is <termref def="dt-namespace-sensitive">namespace-sensitive</termref>
                  <phrase role="xquery">when <termref def="dt-construction-mode">construction
               mode</termref> is <code nobreak="false">preserve</code> and <termref def="dt-copy-namespaces-mode">copy-namespaces mode</termref> is <code nobreak="false">no-preserve</code>
                  </phrase>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0087"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the encoding specified
            in a Version Declaration does not conform to the definition of <code nobreak="false">EncName</code>
            specified in <bibref ref="XML"/>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0088"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the literal that
            specifies the target namespace in a <termref def="dt-module-import">module
               import</termref> or a <termref def="dt-module-declaration">module
               declaration</termref> is of zero length.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0089"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if a variable bound in a
               <code nobreak="false">for</code> or <code nobreak="false">window</code> clause of a FLWOR expression, and its
            associated positional variable, do not have distinct names (<termref def="dt-expanded-qname">expanded QNames</termref>).</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0090"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if a <termref def="dt-character-reference">character reference</termref> does not identify a valid
            character in the version of XML that is in use.</p>
            </error>
            <error spec="XQ" code="0091" class="DY" type="dynamic">
               <p>An implementation <termref def="may">MAY</termref> raise a <termref def="dt-dynamic-error">dynamic error</termref> if an <code nobreak="false">xml:id</code> error, as
            defined in <bibref ref="XMLID"/>, is encountered during construction of an attribute
            named <code nobreak="false">xml:id</code>.</p>
            </error>
            <error spec="XQ" code="0092" class="DY" type="dynamic">
               <p>An implementation <termref def="may">MAY</termref> raise a <termref def="dt-dynamic-error">dynamic error</termref> if a constructed attribute named
               <code nobreak="false">xml:space</code> has a value other than <code nobreak="false">preserve</code> or
               <code nobreak="false">default</code>.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0093" class="ST" type="static">
<p>
It is a <termref def="dt-static-error">static
error</termref> to import a module M<sub>1</sub> if there exists a sequence of modules M<sub>1</sub> ... M<sub>i</sub> ... M<sub>1</sub> such that each module <termref def="dt-module-directly-depends">directly depends</termref> on the next module in the sequence (informally, if M<sub>1</sub> depends on itself through some chain of module dependencies.)</p>
</error>
-->
            <error spec="XQ"
                   role="xquery"
                   code="0094"
                   class="ST"
                   type="static">
               <p> The name of each grouping variable must be equal (by the <code nobreak="false">eq</code> operator on
               <termref def="dt-expanded-qname">expanded QNames</termref>) to the name of a variable
            in the input tuple stream.</p>
            </error>
            <!--
<error spec="XQ" role="xquery" code="0095" class="DY" type="dynamic">
<p>
In the <code>group by</code> clause of a FLWOR expression, it is a <termref def="dt-dynamic-error">dynamic error</termref>
if the value bound to a grouping  variable consists of a sequence of more than one item.</p>
</error> -->
            <!-- ################ -->
            <error spec="XQ" code="0096" class="DY" type="dynamic"><!-- 	   <change diff="chg" at="XQ.E19"> -->
               <p>It is a <termref def="dt-dynamic-error">dynamic error</termref>
                  <phrase diff="add">if</phrase> the node-name of a node constructed by a computed element
            constructor has any of the following properties: </p>
               <ulist>
                  <item>
                     <p>Its namespace prefix is <code nobreak="false">xmlns</code>. </p>
                  </item>
                  <item>
                     <p>Its namespace URI is <code nobreak="false">http://www.w3.org/2000/xmlns/</code>. </p>
                  </item>
                  <item>
                     <p>Its namespace prefix is <code nobreak="false">xml</code> and its namespace URI is not
                     <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>. </p>
                  </item>
                  <item>
                     <p>Its namespace prefix is other than <code nobreak="false">xml</code> and its namespace URI is
                     <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>. </p>
                  </item>
               </ulist>
               <!--	    </change>          -->
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0097"
                   class="ST"
                   type="static">
               <p> It is a static error for a decimal-format to specify a value that is not valid for a
            given property, as described in <termref def="dt-static-decimal-formats">statically
               known decimal formats</termref>
               </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0098"
                   class="ST"
                   type="static">
               <p> It is a static error if, for any named or unnamed decimal format, the properties
            representing characters used in a picture string do not each have distinct values. 
            <phrase diff="chg" at="2015-07-07">
              The following properties represent characters used in a picture
              string: 
                <termref def="id-static-decimal-format-decimal-separator">decimal-separator</termref>, 
                <termref def="id-static-decimal-format-exponent-separator">exponent-separator</termref>, 
                <termref def="id-static-decimal-format-grouping-separator">grouping-separator</termref>,
                <termref def="id-static-decimal-format-percent">percent</termref>, 
                <termref def="id-static-decimal-format-per-mille">per-mille</termref>, 
                the family of ten decimal digits starting with <termref def="id-static-decimal-format-zero-digit">zero-digit</termref>, 
                <termref def="id-static-decimal-format-digit">digit</termref>, and 
                <termref def="id-static-decimal-format-pattern-separator">pattern-separator</termref>.
            </phrase>
               </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0099"
                   class="ST"
                   type="static">
               <p>
                  <phrase diff="del">A <code nobreak="false">ContextItemDecl</code> must not occur after an expression
               that relies on the initial context item, and no query</phrase>
                  <phrase diff="add">No
               module</phrase> may contain more than one ContextItemDecl. </p>
            </error>
            <!--
<error  spec="XQ" role="xquery" code="0100" class="ST" type="static">
<p>(Not currently used.)
</p>
  <ulist>

  <item><p><termref
  def="id-static-decimal-separator">decimal-separator</termref></p></item>
  <item><p><termref
    def="id-static-decimal-format-grouping-separator">grouping-separator</termref></p></item>

    <item><p><termref
    def="id-static-decimal-format-percent">percent-sign</termref></p></item>

    <item><p><termref
    def="id-static-decimal-format-per-mille">per-mille-sign</termref></p></item>

    <item><p><termref
		 def="id-static-decimal-format-zero-digit">zero-digit</termref></p></item>

    <item><p><termref def="id-static-decimal-format-digit">digit-sign</termref></p></item>
    <item><p><termref def="id-static-decimal-format-pattern-separator">pattern-separator-sign</termref></p></item>
  </ulist>
</error>
-->
            <error spec="XQ" code="0101" class="DY" type="dynamic">
               <p>An error is raised if a computed namespace constructor attempts to do any of the
            following:</p>
               <ulist>
                  <item>
                     <p>Bind the prefix <code nobreak="false">xml</code> to some namespace URI other than
                     <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>. </p>
                  </item>
                  <item>
                     <p>Bind a prefix other than <code nobreak="false">xml</code> to the namespace URI
                     <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>. </p>
                  </item>
                  <item>
                     <p>Bind the prefix <code nobreak="false">xmlns</code> to any namespace URI. </p>
                  </item>
                  <item>
                     <p>Bind a prefix to the namespace URI <code nobreak="false">http://www.w3.org/2000/xmlns/</code>.
               </p>
                  </item>
                  <item>
                     <p diff="add">Bind any prefix (including the empty prefix) to a zero-length namespace
                  URI.</p>
                  </item>
               </ulist>
            </error>
            <error spec="XQ" code="0102" class="DY" type="type">
               <p> In an element constructor, if two or more namespace bindings in the in-scope bindings
            would have the same prefix, then an error is raised if they have different URIs; if they
            would have the same prefix and URI, duplicate bindings are ignored. </p>
               <p> If the name of an element in an element constructor is in no namespace, creating a
            default namespace for that element using a computed namespace constructor is an error.
         </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0103"
                   class="ST"
                   type="static">
               <p>All variables in a <code nobreak="false">window</code> clause must have distinct names.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0104"
                   class="ST"
                   type="static">
               <p>A <nt def="prod-xquery40-TypeName">TypeName<!--$spec = xquery40--></nt> that is specified in a <code nobreak="false">validate</code>
            expression must be found in the <termref def="dt-issd">in-scope schema
               definitions</termref>
               </p>
            </error>
            <error spec="XQ" code="0105" class="TY" type="type">
               <p> It is a <termref def="dt-type-error">type error</termref> if the content sequence of an
            element or document constructor contains a function item.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0106"
                   class="ST"
                   type="static">
               <p diff="add"> It is a <termref def="dt-static-error">static error</termref> if a function
            declaration contains both a <code nobreak="false">%private</code> and a <code nobreak="false">%public</code>
            annotation.</p>
               <p diff="del"> It is a <termref def="dt-static-error">static error</termref> if a
            function’s annotations contain more than one annotation named <code nobreak="false">%private</code> or
               <code nobreak="false">%public</code>, more than one <code nobreak="false">%private</code> annotation, or more than
            one <code nobreak="false">%public</code> annotation.</p>
               <p diff="del"> It is a <termref def="dt-static-error">static error</termref> if a
            function’s annotations contain more than one annotation named
               <code nobreak="false">%deterministic</code> or <code nobreak="false">%nondeterministic</code>. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0108"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if an <termref def="dt-output-declaration">output declaration</termref> occurs in a <termref def="dt-library-module">library module</termref>. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0109"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the local name of an
            output declaration in the <code nobreak="false">http://www.w3.org/2010/xslt-xquery-serialization</code>
            namespace is not one of the serialization parameter names listed in <specref ref="id-xq-static-context-components"/>, <phrase diff="add">or if the name of an
               output declaration is <code nobreak="false">use-character-maps</code>
                  </phrase>. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0110"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the same serialization
            parameter is used more than once in an <termref def="dt-output-declaration">output
               declaration</termref>.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0111"
                   class="ST"
                   type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> for a query prolog to
            contain two decimal formats with the same name, or to contain two default decimal
            formats. </p>
            </error>
            <!-- ################ 0112 -->
            <error spec="XQ"
                   role="xquery"
                   code="0113"
                   class="ST"
                   type="static">
               <p> Specifying a <nt def="prod-xquery40-VarValue">VarValue<!--$spec = xquery40--></nt> or <nt def="prod-xquery40-VarDefaultValue">VarDefaultValue<!--$spec = xquery40--></nt> for a context item declaration in a library module is a
               <termref def="dt-static-error">static error</termref>. </p>
            </error>
            <error role="xquery"
                   spec="XQ"
                   code="0114"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> for a decimal format
            declaration to define the same property more than once. </p>
            </error>
            <error role="xquery"
                   spec="XQ"
                   code="0115"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if the document specified
            by the option <code nobreak="false">Q{http://www.w3.org/2010/xslt-xquery-serialization}parameter-document</code>
            raises a serialization error. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0116"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref>
                  <phrase diff="del">if a variable declaration’s annotations contain more than one
               annotation named <code nobreak="false">%private</code> or <code nobreak="false">%public</code>.</phrase>
                  <phrase diff="add">if a variable declaration contains both a <code nobreak="false">%private</code> and a
                  <code nobreak="false">%public</code> annotation, more than one <code nobreak="false">%private</code> annotation,
               or more than one <code nobreak="false">%public</code> annotation.</phrase>
               </p>
            </error>
            <error spec="XP" code="0117" class="TY" type="type"><!-- Bug 28588 -->
               <p>When applying the <termref def="dt-coercion-rules"/>, if an item is of type <code nobreak="false">xs:untypedAtomic</code> and the
            expected type is <termref def="dt-namespace-sensitive">namespace-sensitive</termref>, a
               <termref def="dt-type-error">type error</termref>
                  <errorref class="TY" code="0117"/> is raised. </p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0118"
                   class="ST"
                   type="static">
               <p>In a direct element constructor, the name used in the end tag must exactly match the
            name used in the corresponding start tag, including its prefix or absence of a
            prefix.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0119"
                   class="ST"
                   type="static">
               <p>It is a static error if the implementation is not able to process the value of an
               <code nobreak="false">output:parameter-document</code> declaration to produce an XDM instance.</p>
            </error>
            <!--
<error  spec="XQ" role="xquery" code="0121" class="ST" type="static">
<p>It is a static error if a feature specified in <code>prohibit-feature</code> is supported by the implementation.</p>
</error>
-->
            <!--
<error  spec="XQ" role="xquery" code="0124" class="ST" type="static" diff="del">
<p>
It is a static error if the name of a feature in
<code>require-feature</code> or <code>prohibit-feature</code> is not recognized by the implementation.
</p>
</error>
-->
            <error role="xquery"
                   spec="XQ"
                   code="0125"
                   class="ST"
                   type="static"
                   diff="add">
               <p> It is a <termref def="dt-static-error">static error</termref> if an inline function
               <phrase diff="add">expression</phrase> is annotated as <code nobreak="false">%public</code> or
               <code nobreak="false">%private</code>. </p>
            </error>
            <!--
<error  spec="XQ" role="xquery" code="0127" class="ST" type="static" diff="add">
<p>
  It is a <termref def="dt-static-error">static error</termref> if a
  given feature is both required and prohibited, directly or indirectly, in a module.
</p>
</error>
-->
            <!--<error spec="XQ" role="xquery" code="0129" class="ST" type="static"  diff="del" at="2023-01-29">
         <p>An implementation that does not provide the Higher-Order Function Feature <termref
               def="must">MUST</termref> raise a static error <errorref class="ST" code="0129"/> if
            it encounters a <nt def="FunctionTest">FunctionTest</nt>, <termref
               def="dt-dynamic-function-invocation">dynamic function call</termref>, <termref
               def="dt-named-function-ref">named function reference</termref>, <termref
               def="dt-inline-func">inline function expression</termref>, or <termref
               def="dt-partial-function-application">partial function application</termref>. </p>
      </error>
-->
            <error spec="XP" code="0130" class="DY" type="dynamic">
               <p>An implementation-dependent limit has been exceeded.</p>
            </error>
            <!--
<error  spec="XQ" role="xquery" code="0132" class="ST" type="static">
<p>The <code>module</code> feature can only be required or prohibited in a main module, not in a library module.</p>
</error>
-->
            <!--
      <error spec="XP" code="0133" class="ST" type="static" diff="del">

         <p>It is a <termref def="dt-static-error">static error</termref>
            <errorref class="ST" code="0133"/> if the namespace URI for an EQName is
               <code>http://www.w3.org/2000/xmlns/</code>.</p>
      </error>
-->
            <error spec="XQ" code="0134" class="ST" type="static">
               <p>The namespace axis is not supported.</p>
            </error>
            <!-- DELETED
<error  spec="XP" role="xquery" code="0135" class="ST" type="static" diff="del">
<p> A processor may raise an error  <errorref code="0034" class="ST"/> if the modules of a query do not have the same version number.</p>
</error>
-->
            <!--  DELETED
      <error spec="XQ" code="0136" class="DY" type="dynamic">
         <p>A map key must be a single atomic item.</p>
      </error>
-->
            <error spec="XQ" code="0137" class="DY" type="dynamic">
               <p>No two keys in a map may have the  <termref def="dt-same-key">same key value</termref>.</p>
            </error>
            <!--  DELETED (bug 28689) 
      <error spec="XP" code="0138" class="DY" type="dynamic">
         <p>Position <code>n</code> does not exist in this array.</p>
      </error>


      <error spec="XP" code="0139" class="DY" type="dynamic">
         <p>The keys in a map constructor cannot contain both
         date/time values with a timezone and date/time values with no
         timezone. 
         </p>
      </error>
-->
            <error spec="XQ" code="0140" class="ST" type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> if a named item type declaration 
            is recursive, unless it satisfies the conditions defined in <specref ref="id-recursive-record-tests"/>.</p>
            </error>
            <error spec="XP" code="0141" class="TY" type="type">
               <p>In a <code nobreak="false">for</code>
                  <phrase role="xquery">clause</phrase>,
         when the keyword <code nobreak="false">member</code> is present, the value of the binding collection
         must be a single array; and when either or both of the keywords <code nobreak="false">key</code> and <code nobreak="false">value</code>
         are present, the value of the binding collection must be a single map.</p>
            </error>
            <error spec="XP" code="0144" class="TY" type="type">
               <p>During the analysis phase, an axis step is classified as <termref def="dt-implausible"/>
            if the combination of the inferred context item type, the choice of axis, and the
            supplied node test, is such that the axis step will always return an empty sequence.</p>
            </error>
            <error spec="XP" code="0145" class="TY" type="type">
               <p>During the analysis phase, a unary or postfix lookup expression is classified as <termref def="dt-implausible"/>
            if the combination of the inferred type of the left-hand operand (or the context item type
            in the case of a unary expression) and the choice of key specifier is such that the lookup expression
            will always return an empty sequence.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0146"
                   class="ST"
                   type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> if two or more item types
            declared or imported by a <termref def="dt-module">module</termref> have equal <termref def="dt-expanded-qname">expanded QNames</termref> (as defined by the <code nobreak="false">eq</code>
            operator.)</p>
            </error>
            <!--<error spec="XP" code="0147" class="ST" type="static">
         <p>It is a <termref def="dt-static-error">static error</termref> if a type used as a member
         type in a <nt def="LocalUnionType">LocalUnionType</nt> is not a 
         <termref def="dt-generalized-atomic-type"/>.</p>
      </error>-->
            <error spec="XQ"
                   role="xquery"
                   code="0148"
                   class="ST"
                   type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> if an optional parameter
            in a function declaration is followed by a parameter that does not have a default value.</p>
            </error>
            <error spec="XQ"
                   role="xquery"
                   code="0149"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> 
         if the schemas imported by different modules of a query
         are not compatible as defined in <xspecref spec="DM40" ref="schema-consistency"/>.</p>
            </error>
            <!--<error spec="XQ" role="xquery" code="0150" class="ST" type="static">
         <p> It is a <termref def="dt-static-error">static error</termref> 
            if any of the parameters in a variadic function declaration 
            is declared as optional: that is, 
            if a function declaration is annotated as
            <code>%variadic</code> then none of its parameters may 
            contain a <nt def="ParamWithDefault">ParamWithDefault</nt>.</p>
      </error>-->
            <error spec="XQ"
                   role="xquery"
                   code="0151"
                   class="ST"
                   type="static">
               <p> It is a <termref def="dt-static-error">static error</termref> 
            if a node name supplied as a string literal in a computed element or
            attribute constructor does not take the form of an 
            <nt def="doc-xquery40-EQName">EQName<!--$spec = xquery40--></nt>.</p>
            </error>
            <error spec="XP" code="0152" class="ST" type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> 
            if a key type named in a <nt def="prod-xquery40-TypedMapType"><!--$spec = xquery40--></nt> is not a
            <termref def="dt-generalized-atomic-type"/>.</p>
            </error>
            <error spec="XQ" role="xquery" code="0153" class="TY" type="type">
               <p>The expression of a <code nobreak="false">finally</code> clause must return an empty sequence.</p>
            </error>
            <error spec="XP" code="0154" class="ST" type="static">
               <p>It is a <termref def="dt-static-error">static error</termref> 
            if a <nt def="prod-xquery40-URIQualifiedName">URIQualifiedName<!--$spec = xquery40--></nt> includes a prefix but no URI.</p>
            </error>
         </error-list>
      </div1>
      <div1 role="xquery" id="id-mime-type">
         <head>The <code nobreak="false">application/xquery</code> Media Type</head>
         <p>This Appendix 

    specifies the media type for XQuery Version 1.0.  XQuery is a language for querying over

    collections of data from XML data sources, as specified in the main body of this document. This media type is being 

submitted to the IESG (Internet Engineering Steering Group)

for review, approval, and registration with IANA (Internet Assigned Numbers

Authority.)</p>
         <div2 id="id-mime-type-intro">
            <head>Introduction</head>
            <p>

	This document, found at

	<loc xmlns:xlink="http://www.w3.org/1999/xlink"
                    href="http://www.w3.org/TR/xquery/"
                    role="xquery"
                    xlink:type="simple"
                    xlink:show="replace"
                    xlink:actuate="onRequest">http://www.w3.org/TR/xquery/</loc>,

	together with its normative references,  defines the language XQuery Version 1.0.  This Appendix

      provides information about the <code nobreak="false">application/xquery</code> media type,

      which is intended to be used for transmitting queries written in the

      XQuery language.</p>
            <p>This document was prepared by members of the W3C XML Query Working

      Group.  Please send comments to public-qt-comments@w3.org,

      a public mailing list with archives at

      <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                    href="http://lists.w3.org/Archives/Public/public-qt-comments"
                    xlink:type="simple"
                    xlink:show="replace"
                    xlink:actuate="onRequest">http://lists.w3.org/Archives/Public/public-qt-comments</loc>.</p>
         </div2>
         <div2 id="id-registration-of-mime-type">
            <head>Registration of MIME Media Type <code nobreak="false">application/xquery</code>
            </head>
            <p>MIME media type name:  <code nobreak="false">application</code>
            </p>
            <p>MIME subtype name:    <code nobreak="false">xquery</code>
            </p>
            <p>Required parameters:  none</p>
            <p>Optional parameters: none</p>
            <p>The syntax of XQuery is expressed in Unicode but may be written

	with any Unicode-compatible character encoding, including UTF-8 or

	UTF-16, or transported as US-ASCII or ISO-8859-1 with Unicode

	characters outside the range of the given encoding represented using

	an XML-style <code nobreak="false">&amp;#xddd;</code> syntax.</p>
            <div3 id="id-interoperability-considerations">
               <head>Interoperability Considerations</head>
               <p>None known.</p>
            </div3>
            <div3 id="id-applications-of-media-type">
               <head>Applications Using this Media Type</head>
               <p>The public

	  <loc xmlns:xlink="http://www.w3.org/1999/xlink"
                       href="http://www.w3.org/XML/Query/"
                       xlink:type="simple"
                       xlink:show="replace"
                       xlink:actuate="onRequest">XQuery Web page</loc>

	  lists more than two dozen implementations of the XQuery language,

	  both proprietary and open source.</p>
               <p>This <phrase diff="del" at="2014-12-05">new</phrase> media
	type is <phrase diff="del" at="2014-12-05">being</phrase>
	registered to allow for deployment of XQuery on the World Wide
	Web.</p>
            </div3>
            <div3 id="id-file-extensions">
               <head>File Extensions</head>
               <p>The most common file extensions in use for XQuery are

	  <code nobreak="false">.xq</code> and <code nobreak="false">.xquery</code>.</p>
               <p>The appropriate Macintosh file type code is <code nobreak="false">TEXT</code>.</p>
            </div3>
            <div3 id="id-intended-usage">
               <head>Intended Usage</head>
               <p>The intended usage of this media type is for interchange

	of XQuery expressions.</p>
            </div3>
            <div3 id="id-author-change-controller">
               <head>Author/Change Controller</head>
               <p>XQuery was produced by, and is maintained by, the World Wide Web

	Consortium’s XML Query Working Group.  The W3C has change

	control over this specification.</p>
            </div3>
         </div2>
         <div2 id="xquery-mime-encoding">
            <head>Encoding Considerations</head>
            <p>For use with transports that are not 8-bit clean, quoted-printable

    encoding is recommended since the XQuery syntax itself uses the

    US-ASCII-compatible subset of Unicode.</p>
            <p>An XQuery document may contain an <termref def="dt-encoding-declaration">encoding 

declaration</termref> as part of its <termref def="dt-version-declaration">version declaration</termref>:</p>
            <eg role="frag-prolog-parse-test" xml:space="preserve">xquery version "3.1" encoding "utf-8";</eg>
         </div2>
         <div2 id="xquery-mime-recognizing">
            <head>Recognizing XQuery Files</head>
            <p>An XQuery file may have the string <code nobreak="false">xquery version "V.V"</code> near the

    beginning of the document, where <code nobreak="false">"V.V"</code> is a version number.

    Currently the version number, if present, must be <code nobreak="false">"1.0"</code>
               <phrase diff="add" at="2014-12-05">, <code nobreak="false">"3.0"</code>, or <code nobreak="false">"3.1"</code>
               </phrase>.</p>
         </div2>
         <div2 id="id-charset-default-rules">
            <head>Charset Default Rules</head>
            <p>XQuery documents use the Unicode character set and, by default, the UTF-8 encoding.</p>
         </div2>
         <div2 id="id-security-considerations">
            <head>Security Considerations</head>
            <p>Queries written in XQuery may cause arbitrary URIs or IRIs to be

    dereferenced.  Therefore, the security issues of <bibref ref="RFC3987"/> Section 8 should be considered.

    In addition, the contents of resources identified by  <code nobreak="false">file:</code> URIs can in some cases be

    accessed, processed and returned as results. XQuery expressions can invoke any of the functions defined in

<bibref ref="xpath-functions-40"/>. For example, the

<code nobreak="false">fn:doc()</code> and <code nobreak="false">fn:doc-available()</code> functions  allow local filesystem probes as well as

access to any URI-defined resource accessible from the system

evaluating the XQuery expression.

<phrase diff="add" at="bug 30027">
The <code nobreak="false">fn:transform()</code> function allows calls to URI-identified
XSLT transformations which may in turn call external extension functions
and access or write to the file system. The <code nobreak="false">fn:transform()</code> function
should be sandboxed or disabled if untrusted queries are run.
</phrase>
            </p>
            <p>XQuery is a full declarative programming language, and supports

user-defined functions, external function libraries (modules)

referenced by URI, and system-specific “native” functions.</p>
            <p>Arbitrary recursion is possible, as is arbitrarily large

memory usage, and implementations may place limits on CPU

and memory usage, as well as restricting access to system-defined

functions.

</p>
            <p diff="del" at="2014-12-05">The XML Query Working group is working on a facility to

    allow XQuery expressions to create and update 

    persistent data.  Untrusted queries should not be given write

    access to data.</p>
            <p diff="add" at="2014-12-05">
      The optional XQuery Update Facility allows XQuery expressions to
      create and update persistent data, potentially including writing
      to arbitrary locations on the local filesystem as well as to
      remote URIs. Untrusted queries should not be given write access
      to data.
    </p>
            <p>Furthermore, because the XQuery language permits extensions, 

    it is possible that <code nobreak="false">application/xquery</code>

    may describe content that has

    security implications beyond those described here.</p>
         </div2>
      </div1>
      <inform-div1 id="id-glossary">
         <head>Glossary</head>
         <!-- This processing instruction automatically generates the glossary. -->
         <?glossary?>
      </inform-div1>
      <inform-div1 id="id-atomic-comparisons">
         <head>Atomic Comparisons: An Overview</head>
         <p>This appendix provides a non-normative summary of the various functions and operators used for comparison
    of atomic items, with some background on the history and rationale.</p>
         <p>In XQuery 4.0 there are several ways of comparing two atomic items for equality or ordering.
    The rules for each are summarized in the following sections</p>
         <div2 id="value-comparisons-summary">
            <head>Value Comparisons</head>
            <p>For example <code nobreak="false">$A eq $B</code> or <code nobreak="false">$A lt $B</code>.</p>
            <p>Value comparisons were introduced in XPath 2.0 and XQuery 1.0. One of the aims was to make
          the comparison transitive (a precondition for a wide variety of optimizations), however in edge
          cases involving comparisons across different numeric types this was not entirely achieved.
          To fix this problem, the rules have changed in the 4.0 specification.</p>
            <p>With a value comparison, the rules are:</p>
            <ulist>
               <item>
                  <p>Each operand must either be a single atomic item, or an empty sequence.</p>
               </item>
               <item>
                  <p>If either operand is an empty sequence, the result is an empty sequence; in most
            contexts this has the same effect as returning false.</p>
               </item>
               <item>
                  <p>Strings are compared using the default collation from the static context
          of the expression.</p>
               </item>
               <item>
                  <p>Date and time values are compared after normalizing the timezone offset.
          If the timezone is absent, the implicit timezone from the dynamic evaluation context
          is used.</p>
               </item>
               <item>
                  <p>If nodes are supplied, they are atomized. In the absence of schema validation,
          the result of atomizing a node is an untyped atomic value, which is treated as a string.
          Comparison of a node to a value such as a number or a date therefore raises an error.</p>
               </item>
               <item>
                  <p>Numeric values of types <code nobreak="false">xs:integer</code>, <code nobreak="false">xs:decimal</code>, 
            or <code nobreak="false">xs:float</code> are mutually comparable. Except for the special values <code nobreak="false">NaN</code>
            and positive and negative infinity, both operands
            are converted to <code nobreak="false">xs:decimal</code>, using an implementation of <code nobreak="false">xs:decimal</code>
          that supports unlimited precision (or at least, sufficient precision to represent every
          datum in the <code nobreak="false">xs:double</code> value space losslessly), and the comparison then
          follows the normal mathematical principles.</p>
                  <note>
                     <p>This is a change from previous versions, where both values were converted
            to <code nobreak="false">xs:double</code>. The reason for the change is to make comparisons transitive,
            which is vital for operations such as sorting and grouping.</p>
                  </note>
               </item>
               <item>
                  <p>NaN is not equal to NaN; negative zero is equal to positive zero.</p>
               </item>
               <item>
                  <p>In 4.0, <code nobreak="false">xs:hexBinary</code> and <code nobreak="false">xs:base64Binary</code> values are mutually comparable:
            they are equal if they represent the same sequence of octets.</p>
               </item>
               <item>
                  <p>Comparing incompatible values (for example <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:date</code>)
            raises an error.</p>
               </item>
            </ulist>
         </div2>
         <div2 id="general-comparisons-summary">
            <head>General Comparisons</head>
            <p>For example <code nobreak="false">$A = $B</code> or <code nobreak="false">$A &lt; $B</code>.</p>
            <p>These operators were introduced in XPath 1.0. The semantics were changed significantly in XPath 2.0, but the
          original semantics remain available when XPath 1.0 compatibility mode is enabled.</p>
            <p>The following rules are observed:</p>
            <ulist>
               <item>
                  <p>Either operand may be a sequence; the result is true if any pair of items from the
            two sequences have the required relationship (when compared using a value comparison,
            as described above). For equality tests, the result is reasonably
            intuitive, for example <code nobreak="false">(position() = 1 to 10)</code> is true if the value of 
            <code nobreak="false">position()</code> is equal to any of the values from 1 to 10 inclusive. For other
            operators, the result may be less obvious: for example <code nobreak="false">(position() &gt; 1 to 10)</code>
            has exactly the same meaning as <code nobreak="false">(position() &gt; 1)</code>.</p>
                  <p>In consequence, if either operand is an empty sequence, the result is false.</p>
               </item>
               <item>
                  <p>If nodes are supplied, they are atomized.</p>
               </item>
               <item>
                  <p>Untyped atomic items appearing in one operand are converted to the type of the
            other operand (if both operands are untyped atomic, they are compared as strings).
            As a result, the operator is not transitive: the untyped atomic items <code nobreak="false">"4.0"</code>
            and <code nobreak="false">"4"</code> are not equal to each other, but both compare equal to the integer value 
            <code nobreak="false">4</code>.</p>
               </item>
               <item>
                  <p>As with value comparisons, the result is context-sensitive. In particular, comparison of strings
            uses the default collation from the static context, while comparison of date/time values lacking
            a timezone takes the implicit timezone from the dynamic context.</p>
               </item>
               <item>
                  <p>Comparing incompatible values (for example <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:date</code>)
            raises an error.</p>
               </item>
               <item>
                  <p>For version 4.0, two changes arise as a consequence of the changes
          to value comparisons, described above:</p>
                  <olist>
                     <item>
                        <p>
                           <code nobreak="false">xs:hexBinary</code> and <code nobreak="false">xs:base64Binary</code> values become 
                mutually comparable.</p>
                     </item>
                     <item>
                        <p>Comparison between mixed numeric types (for example <code nobreak="false">xs:decimal</code>
              and <code nobreak="false">xs:double</code>) now converts both values to <code nobreak="false">xs:decimal</code>
              rather than <code nobreak="false">xs:double</code>.</p>
                     </item>
                  </olist>
               </item>
               <item>
                  <p>To mitigate the compatibility impact of the above change, the rules for handling
            untyped atomic values have changed: for example, if <code nobreak="false">$a</code> is an untyped
            attribute node with the value <code nobreak="false">"8.95"</code>, then the comparison
            <code nobreak="false">$a = 8.95</code> remains true. This is because an untyped atomic value is
            now converted to the type of the other operand, which in this case is <code nobreak="false">xs:decimal</code>,
            and the two <code nobreak="false">xs:decimal</code> values compare equal.</p>
               </item>
            </ulist>
         </div2>
         <div2 id="deep-equal-summary">
            <head>fn:deep-equal</head>
            <p>For example, <code nobreak="false">deep-equal($A, $B)</code>
            </p>
            <p>As the name implies, the <code nobreak="false">deep-equal</code> function was introduced primarily for comparing nodes,
          or sequences of nodes; however in its simplest form it can also be used to compare two atomic items. The semantics
          of the comparison used by <code nobreak="false">deep-equal($A, $B)</code> are also invoked by a wide variety of other functions
          including <code nobreak="false">distinct-values</code>, <code nobreak="false">all-equal</code>, and <code nobreak="false">all-different</code>; it is also
          used to underpin grouping constructs in both XQuery 4.0 and XSLT 4.0.</p>
            <p>Some of the relevant rules are:</p>
            <ulist>
               <item>
                  <p>Because <code nobreak="false">deep-equal</code> is used to compare sequences, if one of the operands is an empty
            sequence the result is false; but if both operands are empty sequences, the result is true.</p>
               </item>
               <item>
                  <p>If nodes are supplied, they are not atomized; they are compared as nodes.</p>
               </item>
               <item>
                  <p>Strings can be compared using the default collation or using an explicitly specified collation;
            there are also options to compare after normalizing whitespace or Unicode.</p>
               </item>
               <item>
                  <p>Comparisons of dates and times lacking a timezone uses the implicit timezone from the dynamic
            context.</p>
               </item>
               <item>
                  <p>To ensure that every value is equal to itself, comparing NaN to NaN returns true.</p>
               </item>
               <item>
                  <p>In all other cases comparison between numeric values, including comparison of mixed
            types such as <code nobreak="false">xs:double</code> and <code nobreak="false">xs:decimal</code>, follows the same
            rules as for value comparisons using the <code nobreak="false">eq</code> operator.</p>
               </item>
               <item>
                  <p>
                     <code nobreak="false">xs:hexBinary</code> and <code nobreak="false">xs:base64Binary</code> values are mutually comparable:
            they are equal if they represent the same sequence of octets.</p>
               </item>
               <item>
                  <p>Comparing incompatible values (for example <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:date</code>)
            returns false; it does not raise an error.</p>
               </item>
            </ulist>
         </div2>
         <div2 id="atomic-equal-summary">
            <head>fn:atomic-equal</head>
            <p>For example, <code nobreak="false">atomic-equal($A, $B)</code>
            </p>
            <p>This comparison operation was introduced in XPath 3.0 (and XQuery 3.0) for comparing keys in maps;
          the 4.0 specifications expose it directly as a function that can be called from user applications.
          The dominant requirements for keys in maps were that the comparison should be transitive, error-free, 
          and context-independent. The relevant rules are:</p>
            <ulist>
               <item>
                  <p>The type signature of the function ensures that it can only be used to compare
            single items; empty sequences do not arise.</p>
               </item>
               <item>
                  <p>If nodes are supplied, they are atomized.</p>
               </item>
               <item>
                  <p>Strings are compared codepoint-by-codepoint, without reference to any collation or
            normalization.</p>
               </item>
               <item>
                  <p>Dates and times lacking a timezone are never equal to dates and times that have a timezone.
            However, when comparing two dates or times that both have a timezone, the timezone is normalized.</p>
               </item>
               <item>
                  <p>Comparison of numeric values follows the same rules as <function>deep-equal</function>:
            NaN is considered equal to NaN, positive zero is equal to negative zero, 
            and numeric values of differing type are converted to <code nobreak="false">xs:decimal</code> 
            prior to comparison.</p>
               </item>
               <item>
                  <p>
                     <code nobreak="false">xs:hexBinary</code> and <code nobreak="false">xs:base64Binary</code> values are mutually comparable:
            they are equal if they represent the same sequence of octets. This represents
          an incompatibility with previous versions, in that an <code nobreak="false">xs:hexBinary</code> and <code nobreak="false">xs:base64Binary</code>
          value representing the same sequence of octets can no longer co-exist in the same map;
          they are considered to be duplicate keys.</p>
               </item>
               <item>
                  <p>Comparing incompatible values (for example <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:date</code>)
            returns false; it does not raise an error.</p>
               </item>
            </ulist>
         </div2>
         <div2 id="fn-compare-summary">
            <head>fn:compare</head>
            <p>The function <function>fn:compare</function> was introduced in XPath 3.0 and XQuery 3.0 for comparing
    strings; in 4.0 it has been extended to handle other data types. Unlike <function>fn:deep-equal</function>
    and <code nobreak="false">fn:atomic-equal</code> it establishes the order relationship of two atomic items, rather than
    simply determining whether they are equal.</p>
            <p>Broadly speaking, the <function>fn:compare</function> function establishes the relationship between
    its first two operands in the same way as value comparisons using the <code nobreak="false">eq</code> and <code nobreak="false">lt</code>
    operators. The main differences are:</p>
            <olist>
               <item>
                  <p>
                     <function>fn:compare</function> allows a collation to be supplied explicitly, rather than
      relying on the static context.</p>
               </item>
               <item>
                  <p>
                     <function>fn:compare</function> treats <code nobreak="false">NaN</code> as equal to itself (and less than any
        other numeric value).</p>
               </item>
            </olist>
            <p>All other functions and operations that depend on sorting values (for example the <function>fn:sort</function>,
    <function>fn:sort-by</function>, and <function>fn:sort-with</function> functions, the <function>fn:min</function>
    and <function>fn:max</function> functions, <function>fn:highest</function> and <function>fn:lowest</function>,
    the <code nobreak="false">order by</code> clause in XQuery, and the <code nobreak="false">xsl:sort</code> and <code nobreak="false">xsl:merge</code> instructions
    in XSLT, are ultimately defined in terms of either <code nobreak="false">fn:compare</code> or the value comparison operators
    <code nobreak="false">eq</code> and <code nobreak="false">lt</code>.</p>
         </div2>
         <div2 id="comparison-methods-summary">
            <head>Summary of Atomic Comparison Methods</head>
            <p>The following table summarizes these differences for different ways of comparing values. For all these examples it is assumed that
      (a) the default collation is the HTML case-blind collation, (b) the implicit timezone is
      +01:00, and (c) nodes are untyped.</p>
            <table border="1" role="small">
               <thead>
                  <tr>
                     <th rowspan="1" colspan="1">
                        <code nobreak="false">$A</code>
                     </th>
                     <th rowspan="1" colspan="1">
                        <code nobreak="false">$B</code>
                     </th>
                     <th rowspan="1" colspan="1">
                        <code nobreak="false">$A = $B</code>
                     </th>
                     <th rowspan="1" colspan="1">
                        <code nobreak="false">$A eq $B</code>
                     </th>
                     <th rowspan="1" colspan="1">
                        <code nobreak="false">deep-equal(​$A, $B)</code>
                     </th>
                     <th rowspan="1" colspan="1">
                        <code nobreak="false">atomic-equal(​$A, $B)</code>
                     </th>
                     <th rowspan="1" colspan="1">
                        <code nobreak="false">compare(​$A, $B)</code>
                     </th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">()</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">()</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">()</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">()</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">12</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">()</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">()</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">()</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">(1,2)</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">(2,3)</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">12</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">12e0</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0.2</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0.2e0</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">-1</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">NaN</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">NaN</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">+0e0</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">-0e0</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">"A"</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">"a"</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">"A"</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">12</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">&lt;a&gt;A&lt;/a&gt;</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">"A"</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">&lt;a&gt;12&lt;/a&gt;</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">12</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">error</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">xs:time(​'12:00:00Z')</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">xs:time(​'13:00:00+01:00')</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">xs:time(​'12:00:00Z')</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">xs:time(​'13:00:00')</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">false</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
                  <tr>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">xs:hexBinary(​"0000")</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">xs:base64Binary(​"AAA=")</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">true</code>
                        </p>
                     </td>
                     <td rowspan="1" colspan="1">
                        <p>
                           <code nobreak="false">0</code>
                        </p>
                     </td>
                  </tr>
               </tbody>
            </table>
         </div2>
      </inform-div1>
      <inform-div1 id="id-incompatibilities">
         <head>Backwards Compatibility</head>
         <div2 id="id-incompatibilities-31">
            <head>Incompatibilities relative to XQuery 3.1</head>
            <p>Comparisons between numeric values of different types (for example <code nobreak="false">xs:double</code>
    and <code nobreak="false">xs:decimal</code>) may give a different result, because the values will now be compared
    as decimals rather than as doubles. For example, the comparison <code nobreak="false">3.1 = 3.1e0</code> will now return
    false, because the exact value of the <code nobreak="false">xs:double</code> written as <code nobreak="false">3.1e0</code>
    is actually <code nobreak="false">3.100000000000000088817841970012523233890533447265625</code>. This change is made
    to ensure that comparison operations are fully transitive, which is a prerequisite for certain
    sorting and grouping algorithms.</p>
            <p>In <code nobreak="false">fn:format-integer</code>, certain formatting pictures using a circumflex as a grouping separator might
    be interpreted differently in 4.0: for example <code nobreak="false">format-integer(1234, "9^999")</code> would output <code nobreak="false">"1^234"</code>
      in 3.1, but will output <code nobreak="false">"1621"</code> (1234 in base 9) with 4.0. As a workaround, this can be rewritten as 
      <code nobreak="false">format-integer(1234, "0^000")</code>.</p>
            <p role="xquery">In computed node constructors, the node name must now be written as a QName literal
      (with a preceding <code nobreak="false">#</code> character)
    if it matches certain language keywords. For example <code nobreak="false">element div {}</code> must now be
    written <code nobreak="false">element #div {}</code>. (Alternatively, <code nobreak="false">element { "div" } {}</code>
    and <code nobreak="false">element Q{}div {}</code> are permitted by both XQuery 3.1 and XQuery 4.0.)
    This change is made because <code nobreak="false">{}</code> is now a valid expression representing an
    empty map, so expressions such as <code nobreak="false">element otherwise {}</code> could (without this rule) be 
    parsed in two different ways.</p>
            <p role="xquery">In a pragma, whitespace is now required after the opening <code nobreak="false">(#</code> and
    before the subsequent <code nobreak="false">EQName</code>. This change is made to ensure that an expression
    such as <code nobreak="false">error(#err:XPTY0004)</code> can be parsed as a function call taking a QName literal
    as its argument.</p>
            <p>In XQuery 4.0, certain expressions are classified as <termref def="dt-implausible"/>: an example
    is <code nobreak="false">@code/text()</code>, which will always return an empty sequence. A processor may report
    a static error when such expressions are encountered; however, processors are <rfc2119>required</rfc2119>
    to provide a mode of operation in which such expressions are accepted, thus retaining backwards
    compatibility.</p>
            <p>In expressions that deliver a function item, notably partial function applications, named function references,
    and the <code nobreak="false">fn:function-lookup</code> function, errors may now be detected at the point where the function item
    is created when they were previously detected at the point where the function item was called. This was underspecified
    in previous versions. For example, the partial function application <code nobreak="false">contains(?, 42)</code> is now required to
    raise a type error (because the second argument should be a string, not an integer) at the point where the partial
    function application occurs, not at the point where the resulting function is called.</p>
            <p>As explained in <specref ref="id-function-coercion"/>, the fact that coercion rules are now applied
    to global variables and local variable bindings introduces an incompatibility in the case of variables
    whose value is a function item. Previously it was possible to supply a function item that accepted a wider
    range of argument values than those declared in the variable's type declaration; this is no longer the case.</p>
            <p>Use of an unprefixed function name in a function declaration has a different meaning from XQuery 3.1. In
    3.1 and previous versions, this declared a function in the <termref def="dt-default-function-namespace"/>
    (which would cause an error unless the default function namespace was explicitly set to something other than
    the <code nobreak="false">fn</code> namespace). In XQuery 4.0, the function name will be in no namespace. The distinction will rarely
    be noticed, because an unprefixed function name in a call of such a function will still work in the same way.
    It could make a difference, however, if a function call uses a prefixed name in which the prefix is explicitly
    bound to the default function namespace.</p>
         </div2>
         <div2 id="id-incompatibilities-30">
            <head>Incompatibilities relative to XQuery 3.0</head>
            <p>The following names are now reserved, and cannot appear as function names (see <specref ref="id-reserved-fn-names"/>):</p>
            <ulist>
               <item>
                  <p>
                     <code nobreak="false">map</code>
                  </p>
               </item>
               <item>
                  <p>
                     <code nobreak="false">array</code>
                  </p>
               </item>
            </ulist>
         </div2>
         <div2 id="id-incompatibilities-10">
            <head>Incompatibilities relative to XQuery <phrase role="xquery">1.0</phrase>
            </head>
            <p>The following names are now reserved, and cannot appear as function names (see <specref ref="id-reserved-fn-names"/>):</p>
            <ulist>
               <item>
                  <p>
                     <code nobreak="false">function</code>
                  </p>
               </item>
               <item>
                  <p>
                     <code nobreak="false">namespace-node</code>
                  </p>
               </item>
               <item>
                  <p>
                     <code nobreak="false">switch</code>
                  </p>
               </item>
            </ulist>
            <p>If <code nobreak="false">U</code> is a union type with <code nobreak="false">T</code> as one of its members,
  and if <code nobreak="false">E</code> is an element with <code nobreak="false">T</code> as its type annotation,
  the expression <code role="parse-test" nobreak="false">E instance of element(*, U)</code>
  returns <code nobreak="false">true</code> in both XQuery 3.0 and 3.1.
  In <phrase role="xquery">XQuery 1.0</phrase>,
  it returns <code nobreak="false">false</code>.</p>
            <note>
               <p>This is not an incompatibility with XQuery 3.0.
 It should be included in XQuery 3.0 as an incompatibility with
 <phrase role="xquery">XQuery 1.0</phrase>,
 but it was discovered after publication.</p>
            </note>
         </div2>
      </inform-div1>
      <inform-div1 id="id-revision-log" diff="chg" at="2022-11-16">
         <head>Change Log</head>
         <?change-log?>
      </inform-div1>
   </back>
</spec>
