<spec xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" id="spec-top" w3c-doctype="rec" status="int-review"><header><title>XSLT Streaming</title><version>Version 4.0</version><w3c-designation>REC-xslt-streaming-40</w3c-designation><w3c-doctype>W3C Editor's Draft</w3c-doctype><pubdate><!-- The stylesheet xmlspec-2016.xsl recognizes this as a trigger to insert the current date --><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/xslt-streaming-40/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://qt4cg.org/specifications/xslt-streaming-40/</loc>
      </publoc><altlocs><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="xslt-streaming-40.xml" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Specification in XML format</loc></altlocs><latestloc>
         <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://qt4cg.org/specifications/xslt-streaming-40/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
      </latestloc><prevrec doc="XSL Transformations (XSLT)">
    <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/xslt-30/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/xslt-30/</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><errataloc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/XML/2017/qt-errata/xslt-xquery-serialization-40-errata.html" xlink:type="simple"/><translationloc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/2003/03/Translations/byTechnology?technology=xslt-xquery-serialization-40" xlink:type="simple"/><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><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><p>At the time of writing this specification does not fully describe the streamability of all
       new constructs introduced in XSLT 4.0 and XPath 4.0. This remains a work in progress.</p><note role="dedication" id="dedication"><p>The publications of this community group 
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="../xquery-40/xpath-40.html#dedication" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">are dedicated</loc> to our co-chair,
Michael Sperberg-McQueen (1954–2024).</p></note></status><abstract><p>This document defines the streaming feature of XSLT 4.0.</p><p>The earlier XSLT 3.0 specification integrated the definition of streaming
  into the main language specification, although streaming was always an optional feature.
  In this version, the specification has been modularised so that streaming features
  are described separately. This has been done in order to make the set of specification
  documents more manageable both for editors and for readers.</p></abstract><langusage><language id="en">English</language></langusage><revisiondesc><p>See the GIT changelog.</p></revisiondesc></header><body><div1 id="intro"><head>Introduction</head><changes><change>Use the arrows to browse significant changes since the 3.1 version of this specification.</change><change>Sections with significant changes are marked Δ in the table of contents.</change></changes><p>This document defines the streaming feature of the XSLT 4.0 language: see
<bibref ref="xslt-40"/>.</p><p>Streaming is an optional feature of the XSLT language that enables documents
  to be transformed that are too large to be held in memory. Stylesheets that aim
  to achieve streamed processing must adhere to contraints (called streamability rules)
  that are defined in this specification.</p><div2 id="terminology"><head>Terminology</head><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>Where the phrase <rfc2119>must</rfc2119>, <rfc2119>must not</rfc2119>, or
                  <rfc2119>required</rfc2119> relates to the behavior of the XSLT processor, then an
               implementation is not conformant unless it behaves as specified, subject to the more
               detailed rules in <specref ref="conformance"/>. </p><p>Where the phrase <rfc2119>must</rfc2119>, <rfc2119>must not</rfc2119>, or
                  <rfc2119>required</rfc2119> relates to a stylesheet then the processor
                  <rfc2119>must</rfc2119> enforce this constraint on stylesheets by raising an
               error if the constraint is not satisfied.</p><p>Where the phrase <rfc2119>should</rfc2119>, <rfc2119>should not</rfc2119>, or
                  <rfc2119>recommended</rfc2119> relates to a stylesheet then a processor
                  <rfc2119>may</rfc2119> produce warning messages if the constraint is not
               satisfied, but <rfc2119>must not</rfc2119> treat this as an error.</p><p>
               <termdef id="dt-implementation-defined" term="implementation-defined">In this
                  specification, the term <term>implementation-defined</term> refers to a feature
                  where the implementation is allowed some flexibility, and where the choices made
                  by the implementation <rfc2119>must</rfc2119> be described in documentation that
                  accompanies any conformance claim.</termdef>
            </p><p>
               <termdef id="dt-implementation-dependent" term="implementation-dependent">The term
                     <term>implementation-dependent</term> refers to a feature where the behavior
                     <rfc2119>may</rfc2119> vary from one implementation to another, and where the
                  vendor is not expected to provide a full specification of the behavior.</termdef>
               (This might apply, for example, to limits on the size of source documents that can be
               transformed.)</p><p>In all cases where this specification leaves the behavior implementation-defined or
               implementation-dependent, the implementation has the option of providing mechanisms
               that allow the user to influence the behavior.</p><p>A paragraph labeled as a <term>Note</term> or described as an <term>example</term> is
               non-normative.</p></div2></div1><div1 id="Concepts"><head>Concepts</head><div2 id="streaming-concepts"><head>Streaming</head><p><termdef id="dt-streaming" term="streaming">The term <term>streaming</term> refers to
                  a manner of processing in which XML documents (such as source and result documents)
                  are not represented by a complete tree of nodes occupying memory proportional to
                  document size, but instead are processed “on the fly” as a sequence of events,
                  similar in concept to the stream of events notified by an XML parser to represent
                  markup in lexical XML.</termdef></p><p><termdef id="dt-streamed-document" term="streamed document">A <term>streamed
                     document</term> is a <xtermref spec="XT40" ref="dt-source-tree">source tree</xtermref> that
                  is processed using streaming, that is, without constructing a complete tree of
                  nodes in memory.</termdef></p><p><termdef id="dt-streamed-node" term="streamed node">A <term>streamed
                     node</term> is a node in a <termref def="dt-streamed-document">streamed
                     document</termref>.</termdef></p><p>Many processors implementing earlier versions of this specification adopted an
               architecture that allowed streaming of the <xtermref spec="XT40" ref="dt-result-tree">result
                  tree</xtermref> directly to a serializer, without first materializing the complete
               result tree in memory. Streaming of the <xtermref spec="XT40" ref="dt-source-tree">source
                  tree</xtermref>, however, has proved to be more difficult without subsetting the
               language. This has created a situation where documents exceeding the capacity of
               virtual memory could not be transformed. XSLT 3.0 therefore introduced facilities
               allowing stylesheets to be written in a way that makes streaming of source documents
               possible, without excessive reliance on processor-specific optimization
               techniques.</p><p>Streaming achieves two important objectives: it allows large documents to be
               transformed without requiring correspondingly large amounts of memory; and it allows
               the processor to start producing output before it has finished receiving its input,
               thus reducing latency.</p><p>This specification does not attempt to legislate precisely which implementation
               techniques fall under the definition of streaming, and which do not. A number of
               techniques are available that reduce memory requirements, while still requiring a
               degree of buffering, or allocation of memory to partial results. A stylesheet that
               requests streaming of a source document is indicating that the processor should avoid
               assuming that the entire source document will fit in memory; in return, the
               stylesheet must be written in a way that makes streaming possible. This specification
               does not attempt to describe the algorithms that the processor should actually use,
               or to impose quantitative constraints on the resources that these algorithms should
               consume.</p><p>Nothing in the XSLT specification prevents a processor using streaming whenever it sees an
               opportunity to do so. However, experience has shown that in order to achieve
               streaming, it is often necessary to write stylesheet code in such a way as to make
               this possible. Therefore, XSLT provides explicit constructs allowing the
               stylesheet author to request streaming, and defines explicit static constraints on
               the structure of the code which are designed to make streaming possible.</p><p>A processor that claims conformance with the streaming option offers a guarantee that
               when streaming is requested for a source document, and when the stylesheet conforms
               to the rules that make the processing <termref def="dt-guaranteed-streamable"/>, then
               an algorithm will be adopted in which memory consumption is either completely
               independent of document size, or increases only very slowly as document size
               increases, allowing documents to be processed that are orders-of-magnitude larger
               than the physical memory available. A processor that does not claim conformance with
               the streaming option must still process a stylesheet and deliver the correct results,
               but is not required to use streaming algorithms, and may therefore fail with
               out-of-memory errors when presented with large source documents.</p><p>Apart from the fact that there are constructs to request streaming, and rules that
               must be followed to guarantee that streaming is possible, the language has been
               designed so there are as few differences as possible between streaming and
               non-streaming evaluation. The semantics of the language continue to be expressed in
               terms of the XDM data model, which is substantively unchanged; but readers must take
               care to observe that when terms like “node” and “axis” are used, the concepts are
               completely abstract and may have no direct representation in the run-time execution
               environment.</p><p>Streamed processing of a document can be initiated in one of three ways:</p><ulist><item><p>The <xtermref spec="XT40" ref="dt-initial-mode">initial mode</xtermref> can be declared as a
                        <xtermref spec="XT40" ref="dt-streamable-mode">streamable mode</xtermref>. In this case
                     the <xtermref spec="XT40" ref="dt-initial-match-selection"/> will generally be a document node (or
                        sequence of document nodes), supplied by the calling application in
                     a form that allows streaming (that is, in some form other than a tree in
                     memory; for example, as a reference to a push or pull XML parser primed to
                     deliver a stream of events). The type of
                        these nodes can be constrained by using the attribute
                           <code nobreak="false">on-no-match="fail"</code> on the <xtermref spec="XT40" ref="dt-initial-mode"/>,
                        and using this mode only for processing the top-level nodes.
                     </p></item><item><p>Streamed processing of any document can be initiated using the
                        <elcode>xsl:source-document</elcode> instruction. This has an attribute  
                        <code nobreak="false">href</code> whose value is the URI of a document to be processed,
                     and an attribute <code nobreak="false">streamable</code> that
                     indicates whether it is to be processed using
                     streaming; the actual processing to be applied is defined by the
                     instructions written as children of the <elcode>xsl:source-document</elcode>
                     instruction. </p></item><item><p>Streamed merging of a set of input documents can be initiated using the
                        <elcode>xsl:merge</elcode> instruction.</p></item></ulist><p>The rules for streamability, which are defined in detail in <specref ref="streamability"/>, impose two main constraints:</p><ulist><item><p>The only nodes reachable from the node that is currently being processed are
                     its attributes and namespaces, its ancestors and their attributes and
                     namespaces, and its descendants and their attributes and namespaces. The
                     siblings of the node, and the siblings of its ancestors, are not reachable in
                     the tree, and any attempt to use their values is a 
                    <xtermref spec="XT40" ref="dt-static-error">static error</xtermref>. </p></item><item><p>When processing a given node in the tree, each descendant node can only be
                     visited once. Essentially this allows two styles of processing: either visit
                     each of the children once, and then process that child with the same
                     restrictions applied; or process all the descendants in a single pass, in which
                     case it is not possible while processing a descendant to make any further
                     downward selection.</p></item></ulist><p>The second restriction, that only one visit to the children is
               allowed, means that XSLT code that was not designed with streaming in mind will often
               need to be rewritten to make it streamable. In many cases it is possible to do this
               using a technique sometimes called <emph>windowing</emph> or <emph>burst-mode
                  streaming</emph> (note this is not quite the same meaning as
                  <emph>windowing</emph> in XQuery 3.0). Many XML documents consist of a large
               number of elements, each of manageable size, representing transactions or business
               objects where each such element can be processed independently: in such cases, an
               effective design pattern is to write a streaming transformation that takes a snapshot
               of each element in turn, processing the snapshot using the full power of the XSLT
               language. Each snapshot is a tree built in memory and is therefore fully navigable.
               For details see the <function>snapshot</function> and <function>copy-of</function>
               functions.</p><p>The new facility of <emph>accumulators</emph> allows applications
               complete control over how much information is retained (and by implication, how much
               memory is required) in the course of a pass over a <termref def="dt-streamed-document"/>. An accumulator computes a value for every node in a
               streamed document: or more accurately, two values, one for the first visit to a node
               (before visiting its descendants), and a second value for the second visit to the
               node (after visiting the descendants). The computation is structured in such a way
               that the value for a given node can depend only on the value for the previous node in
               document order together with the data available when positioned at the current node
               (for example, the attribute values). Based on the well-established fold operation of
               functional programming languages, accumulators provide the convenience and economy of
               mutable variables while remaining within the constraints of a purely declarative
               processing model.</p><p>When streaming is initiated, for example using the
                  <elcode>xsl:source-document</elcode> instruction, it is necessary to declare which
               accumulators are applicable to the streamed document.</p><p>Streaming applications often fall into one of the following categories:</p><ulist><item><p>Aggregation applications, where a single aggregation operation (perhaps
                        <xfunction>count</xfunction>, <xfunction>sum</xfunction>,
                        <xfunction>exists</xfunction>, or <xfunction>distinct-values</xfunction>) is
                     applied to a set of elements selected from the streamed source document by
                     means of a path expression.</p></item><item><p>Record-at-a-time applications, where the source document consists of a long
                     sequence of elements with similar structure (“records”), and each “record” is
                     processed using the same logic, independently of any other “records”. This kind
                     of processing is facilitated using the <function>snapshot</function> and
                        <function>copy-of</function> function mentioned earlier.</p></item><item><p>Grouping applications, where the output follows the structure of the input,
                     except that an extra layer of hierarchy is added. For example, the input might
                     be a flat series of banking transactions in date/time order, and the output
                     might contain the same transactions grouped by date.</p></item><item><p>Accumulator applications, which are the same as record-at-a-time applications,
                     except that the processing of one “record” might depend on data encountered
                     earlier in the document. A classic example is processing a sequence of banking
                     transactions in which the input transaction contains a debit or credit amount,
                     and the output adds a running total (the account balance). The
                        <elcode>xsl:iterate</elcode> instruction has been introduced to facilitate
                     this style of processing.</p></item><item><p>Isomorphic transformations, in which there is an ordered (often largely
                     one-to-one) relationship between the nodes of the source tree and the nodes of
                     the result tree: for example, transformations that involve only the renaming or
                     selective deletion of nodes, or scalar manipulations of the values held in the
                     leaf nodes. Such transformations are most conveniently expressed using
                     recursive application of template rules. This is possible with a streamed input
                     document only if all the template rules adhere to the constraints required for
                     streamability. To enforce these rules, while still allowing unrestricted
                     processing of other documents within the same transformation, all streaming
                     evaluation must be carried out using a specific 
                    <xtermref spec="XT40" ref="dt-mode">mode</xtermref>, which is declared 
                    to be a streaming mode by means of an
                        <elcode>xsl:mode</elcode> declaration in the stylesheet.</p></item></ulist><p>There are important classes of application in which streaming is possible only if
               multiple streams can be processed in parallel. This specification therefore provides
               facilities:</p><olist><item><p>allowing multiple sorted input sequences to be merged into one sorted output
                     sequence (the <elcode>xsl:merge</elcode> instruction)</p></item><item><p>allowing multiple output sequences to be generated during a single pass of an
                     input sequence (the <elcode>xsl:fork</elcode> instruction).</p></item></olist><p>These facilities have been designed in such a way that they can readily be
               implemented using streaming, that is, without materializing the input or output
               sequences in memory.</p></div2><div2 id="streamed-validation"><head>Streamed Validation</head><p>Streaming can be combined with schema-aware processing: that is, the streamed input to a transformation 
               can be subjected to on-the-fly validation, a process which typically accepts an input stream from the 
               XML parser and delivers an output stream (of type-annotated nodes) to the transformation processor. 
               The XSD specification is designed so that validation is, with one or two exceptions, a streamable process. 
               The exceptions include:
            </p><ulist><item><p>There may be a need to allocate memory to hold keys, in order to enforce uniqueness and 
                  referential integrity constraints (<code nobreak="false">xs:unique</code>, <code nobreak="false">xs:key</code>, <code nobreak="false">xs:keyref</code>).
               </p></item><item><p>In XSD 1.1, assertions can be defined by means of XPath expressions. These are not constrained 
                  to be streamable; in the general case, any subtree of the document that is validated using an assertion 
                  may need to be buffered in memory while the assertion is processed.
               </p></item></ulist><p>Applications that need to run in finite memory may therefore need to avoid these XSD features, 
               or to use them with care.
            </p><p>XSD is designed so that the intended type of an element (the “governing type”) can be determined as soon 
               as the start tag of the element is encountered: the process of validation checks whether the content of 
               the element actually conforms to this type, and by the time the end tag is encountered, the process will 
               have established either that the element is valid against the governing type, or that it is invalid. 
            </p><p>By default, dynamic errors occurring during streamed processing are fatal: they typically cause the 
               transformation to fail immediately. XSLT 3.0 introduced the ability to catch dynamic errors and recover 
               from them. Schema invalidity, however, is treated as a dynamic error of the instruction that 
               processes the entire input stream, so after a validation failure, no further processing of that input stream 
               is possible.
            </p><p>In consequence, a streamed validator that is running in tandem with a streamed transformation 
               can present the transformer with element nodes that carry a provisional type annotation representing 
               the type that the element will have if it turns out to be valid. As soon as a node is encountered that 
               violates this assumption, the validator should stop the flow of data to the transformer, so that the 
               transformer never sees invalid data. This allows the stylesheet code to be compiled with the assumption 
               of type-safety: at run-time, all nodes seen by the transformation will conform to their XSLT-declared types
               (for example, a type declared implicitly using <code nobreak="false">match="schema-element(invoice)"</code> on an 
               <elcode>xsl:template</elcode> element).
            </p><p>A streamed transformation that only accesses part of the input document (for example, a header
               at the start of a document) is not required to continue reading once the data it needs 
               has been read. This means that XML well-formedness or validity errors occurring in the unread part 
               of the input stream may go undetected.
            </p><note><p>The analysis of guaranteed streamability (see <specref ref="streamability"/>)
             takes no account of information that might be obtained from a schema-aware
             static analysis of the stylesheet. Implementations may, however, be able to use
             streaming strategies for stylesheets that are not guaranteed-streamable, by
             taking advantage of such information. For example, an implementation might be
             able to treat the expression <code nobreak="false">.//title</code> as <termref def="dt-striding"/> rather than <termref def="dt-crawling"/> if it can
             establish from knowledge of the schema that two <code nobreak="false">title</code> elements
             will never be nested one inside the other.</p></note></div2><div2 id="initiating-streaming"><head>Initiating a Streamed Transformation</head><p>With a streamable processor, the <xtermref spec="XT40" ref="dt-initial-match-selection"/>&gt; can consist
                  of streamed nodes, but the <xtermref spec="XT40" ref="dt-global-context-item"/> is always <termref def="dt-grounded"/>,
                  because it is available to all global variables and there is no control over the sequence of processing.</p><p>If the initial mode is <termref def="dt-declared-streamable"/>,
                     then a streaming processor <rfc2119>should</rfc2119> allow some or all of the items
                     in the <xtermref spec="XT40" ref="dt-initial-match-selection"/> to be nodes supplied in streamable form,
                     and any nodes that are supplied in this form <rfc2119>must</rfc2119> then be processed using streaming.</p><p>Since the <xtermref spec="XT40" ref="dt-global-context-item"/> cannot be a streamed node,
                  in cases where the transformation is to proceed by applying streamable templates
                  to a streamed input document, the <xtermref spec="XT40" ref="dt-global-context-item"/> must
                  either be absent, or must be something that differs from the 
                    <xtermref spec="XT40" ref="dt-initial-match-selection"/>.</p></div2><div2 id="streaming-non-xml"><head>Streaming of non-XML data</head><p>The facilities in this specification designed to enable large data sets to be processed in a streaming
            manner are oriented almost entirely to XML data. This does not mean that there is never a requirement
            to stream non-XML data, or that the Working Group has ignored this requirement; rather, the Working Group
            has concluded that for the most part, streaming of non-XML data can be achieved by implementations without
            the need for specific language features in XSLT.</p><p>To make streamed processing of unparsed text files easier, the function <xfunction>unparsed-text-lines</xfunction>
            has been introduced. This is not only more convenient for stylesheet authors than reading the entire input
            using the <xfunction>unparsed-text</xfunction> function and then tokenizing the result, it is also easier for implementations
            to optimize, allowing each line of text to be discarded from memory after it has been processed.</p><p>For all functions that access external data, including <function>document</function>, <xfunction>doc</xfunction>,
            <xfunction>collection</xfunction>, <xfunction>unparsed-text</xfunction>, <xfunction>unparsed-text-lines</xfunction>,
            and <xfunction>json-doc</xfunction>, the requirements on determinism can now
            be relaxed using <termref def="dt-implementation-defined"/> configuration options. This is significant
            because it means that when a transformation reads the same external resource more than once, it becomes
            legitimate for the contents of the resource to be different on different invocations, and this eliminates
            the need for the processor to cache the contents of the resource in memory.</p><p>In the XDM data model, every value is a sequence, and (as with most functional programming languages),
            processing of sequences of items is pervasive throughout the XSLT and XPath languages and their function
            library. Good performance of a functional programming language often depends on sequence-based operations
            being pipelined, and being evaluated in a lazy fashion (that is, many operations process items in a sequence
            one at a time, in order; and many operations can deliver a result without processing the entire sequence).
            The semantics of XSLT and XPath permit pipelined and lazy evaluation (for example, the error handling semantics
            are carefully written to ensure this), but they do not require it: the details are left to implementations.
            Pipelined processing of a sequence is not the same thing as streamed processing of a tree, and where the XSLT
            specification talks of operations being “guaranteed streamable”, this is always referring to processing of
            trees, not of sequences.</p><p>The facilities for streaming of XML trees include operations such as <function>copy-of</function>
            and <function>snapshot</function> which are able to take a sequence of streamed nodes as input, 
               and produce a sequence of in-memory (unstreamed) nodes as output. It is also possible to generate
               a sequence of strings or other atomic items through the process of <xtermref spec="XT40" ref="dt-atomization">atomization</xtermref>.
               The actual memory usage of a streamed
            XSLT application may depend significantly on whether the processing of the resulting sequence of in-memory
            nodes or atomic items is pipelined or not. The specification, however, has nothing to say on this matter: 
            it is considered an area where implementers can exercise their discretion and ingenuity.</p><p>Streaming of JSON input receives little attention in this specification. One can envisage an implementation
            of the <function>json-to-xml</function> function in which the XML delivered by the function consists of
            streamed nodes; but the Working Group has not researched the feasibility of such an implementation in any detail.</p></div2><div2 id="model-for-streaming"><head>Data Model for Streaming</head><div3 id="streamed-documents"><head>Streamed Documents</head><p>The data model for nodes in a document that is being streamed is no different from
               the standard XDM data model, in that it contains the same objects (nodes) with the
               same properties and relationships. The facilities for streaming do not change the
               data model; instead they impose rules that limit the ability of stylesheets to
               navigate the data model.</p><p>A useful way to visualize streaming is to suppose that at any point in time, there is
               a current position in the streamed input document which may be the start or end of
               the document, the start or end tag of an element, or a text, comment, or processing
               instruction node. From this position, the stylesheet has access to the following
               information: </p><ulist><item><p>Properties intrinsic to the node, such as its name, its base URI, its type
                     annotation, and its <code nobreak="false">is-id</code> and <code nobreak="false">is-idref</code>
                     properties.</p></item><item><p>The ancestors of the node (but navigation downwards from the ancestors is not
                     permitted).</p></item><item><p>The attributes of the node, and the attributes of its ancestors. For each such
                     attribute, all the properties of the node including its string value and typed
                     value are available, but there are limitations that restrict navigation from
                     the attribute node to other nodes in the document.</p></item><item><p>The in-scope namespace bindings of the node.</p></item><item><p>In the case of attributes, text nodes, comments, and processing instructions,
                     the string value and typed value of the node.</p></item><item><p>In the case of element nodes, whether or not the element has children. This
                     information is obtained by calling the <xfunction>has-children</xfunction>
                     function. This implies that the processor performs look-ahead (limited to a
                     single token) to determine whether the start tag is immediately followed by a
                     matching end tag.</p></item><item><p>In the case of document nodes, details of unparsed entities in the document.
                     This information is obtained by calling the
                        <function>unparsed-entity-uri</function> and
                        <function>unparsed-entity-public-id</function> functions. A processor might
                     enable this by reading the DTD as soon as the document is opened. Since
                     comments and processing instructions that precede the DOCTYPE declaration are
                     available as children of the document node, this also implies that a streaming
                     processor needs sufficient memory to hold these comments and processing
                     instructions until the start tag of the first element is encountered.
                     Information about unparsed entities remains available for the duration of
                     processing, in the same way as attributes of ancestor elements.</p></item></ulist><p>The children and other descendants of a node are not accessible except as a
               by-product of changing the current position in the document. The same applies to
               properties of an element or document node that require examination of the
               node’s descendants, that is, the string value and typed value. This is
               enforced by means of a rule that only one expression requiring downward navigation
               from a node is permitted.</p><p>Information about the type of a node is in general
               considered a property intrinsic to the node, and is available without advancing the
               input stream. There is an exception for an expression of the form <code nobreak="false">(/) instance
                  of document-node(element(invoice))</code>. This is not guaranteed streamable,
               because it requires reading ahead to check that the document node has only one
               element child. However, a processor that knows that the parser delivering the
               document stream is only capable of delivering well-formed documents may use this
               knowledge (along with the limited look-ahead needed to get the name of the outermost
               element) to make this expression streamable.</p><p>A streaming processor is not
                  required to read any more of the source document than is needed to
               generate correct stylesheet output. It is not required to read the full source
               document merely in order to satisfy the requirement imposed by the XML Recommendation
               that an XML Processor must report violations of well-formedness in the input.</p><p>More detailed rules are defined in <specref ref="streamability"/>.</p></div3><div3 id="streaming-other-types"><head>Maps and Arrays</head><p>Maps and arrays were first introduced in XPath 3.1.</p><p>Streaming facilities in this specification are, for the most part, relevant 
                  only to streamed processing of XML trees, and not to other structures such as 
                  sequences, maps and arrays, which will typically be held in memory unless 
                  the processor is capable of avoiding this.
               </p><p>Maps, however, play an important role in enabling streamed applications
               to be written. For example, a map can be used as the data structure maintained
               by an accumulator (see <xspecref spec="XT40" ref="accumulators"/>) to remember information
               that has been retrieved from a streamed document, given that it is not possible to
               revisit the same nodes later. There is also a special streamability rule for
               map constructor expressions (see <specref ref="maps-streaming"/>) that allows
               such an expression to make multiple downward selections in the streamed input
               document: for example one can write <code nobreak="false">{ 'authors': data(author), 'editors': data(editor) }</code>,
               which gathers the values of these two elements, or sets of elements, from the input
               stream, regardless what order they appear in — even if they are interleaved.</p><p>The rules for creating maps and arrays are designed to ensure that the 
                  entries in a map, and the members of an array, cannot contain nodes from 
                  a streamed document. This is achieved by the way in which the streamability 
                  properties of the relevant expressions and functions are defined.
               </p><p>By contrast, sequences can and often do contain nodes from streamed documents, 
                  and a major purpose of the rules for streamability is to make this possible.
               </p></div3></div2></div1><div1 id="streamability"><head>Streamability Analysis Principles</head><p>This section describes the principles used to determine
            properties of <termref def="dt-construct">constructs</termref> in the 
           <xtermref spec="XT40" ref="dt-stylesheet"/> that are used
           in the analysis of streamability. Specifically, it introduces
           the concepts of the <termref def="dt-posture"/> and
               <termref def="dt-sweep"/> of a construct, which enable the streamability of
            the stylesheet to be assessed.</p><p>These properties are used, for example, to determine the streamability
            of:</p><ulist><item><p><xtermref spec="XT40" ref="dt-template-rule">Template rules</xtermref>: see <specref ref="streamable-templates"/></p></item><item><p>The <elcode>xsl:source-document</elcode> instruction: see <specref ref="streaming-source-documents"/></p></item><item><p><xtermref spec="XT40" ref="dt-attribute-set">Attribute sets</xtermref>: see <specref ref="streamability-of-attribute-sets"/></p></item><item><p><xtermref spec="XT40" ref="dt-accumulator">Accumulators</xtermref>: see <specref ref="streamability-of-accumulators"/></p></item><item><p><xtermref spec="XT40" ref="dt-stylesheet-function">Stylesheet functions</xtermref>: see <specref ref="streamable-stylesheet-functions"/></p></item><item><p>The <elcode>xsl:merge</elcode> instruction: see <specref ref="streamable-merging"/></p></item></ulist><p>In each case, the conditions for constructs to be <termref def="dt-guaranteed-streamable"/> are defined in terms of these properties. The result
            of this analysis in turn (see <specref ref="streamability-guarantees"/>) imposes rules
            on how the constructs are handled by processors that implement the <termref def="dt-streaming-feature"/>. The analysis has no effect on the behavior of
            processors that do not implement this feature.</p><p>The analysis is relevant to constructs such as streamable template rules and the
               <elcode>xsl:source-document</elcode> instruction that process a single streamed input
            document. The <elcode>xsl:merge</elcode> instruction, which processes multiple streamed
            inputs, has its own rules.</p><p>The rules in this section operate on the expression tree (more properly, construct tree)
            that is typically output by the XSLT and XPath parser. For the most part, the rules
            depend only on identifying the syntactic constructs that are present.</p><p>The rules in this section generally consider each <xtermref spec="XT40" ref="dt-component">component</xtermref> in the stylesheet (and in the case of 
           <xtermref spec="XT40" ref="dt-template-rule">template rules</xtermref>, each template rule) in isolation.
            The exception is that where a component contains references to other components (such as
            global variables, functions, or named templates), then information from the signature of
            the referenced component is sometimes used. This is invariably information that cannot
            be changed if a component is overridden in a different 
           <xtermref spec="XT40" ref="dt-package">package</xtermref>. 
           The analysis thus requires as a pre-condition that function calls
            and calls on named templates have been resolved to the extent that the corresponding
            function/template signature is known. </p><p>The detailed way in which the construct tree is derived from the lexical form of the
            stylesheet is not described in this specification. There are many ways in which the tree
            can be optimized without affecting the result of the rules in this section: for example,
            a sequence constructor containing a single instruction can be replaced by that
            instruction, and a parenthesized expression can be replaced by its content.</p><p><termdef id="dt-construct" term="construct">The term <term>construct</term> refers to
               the union of the following: a <xtermref spec="XT40" ref="dt-sequence-constructor"/>, 
           an <xtermref spec="XT40" ref="dt-instruction">instruction</xtermref>, an 
           <xtermref spec="XT40" ref="dt-attribute-set">attribute set</xtermref>, a 
             <xtermref spec="XT40" ref="dt-value-template">value
                  template</xtermref>, an <xtermref spec="XT40" ref="dt-expression">expression</xtermref>, or a
                  <xtermref spec="XT40" ref="dt-pattern">pattern</xtermref>.</termdef></p><p>These <termref def="dt-construct">constructs</termref> are classified into
               <term>construct kinds</term>: in particular, 
            <xtermref spec="XT40" ref="dt-instruction">instructions</xtermref> are 
            classified according to the name of the XSLT instruction,
            and <xtermref spec="XT40" ref="dt-expression">expressions</xtermref> are classified according to the
            most specific production in the XPath grammar that the expression satisfies. (This
            means, for example, that <code nobreak="false">2+2</code> is classified as an <code nobreak="false">AdditiveExpr</code>,
            rather than say as a <code nobreak="false">UnionExpr</code>; although it also satisfies the production
            rule for <code nobreak="false">UnionExpr</code>, <code nobreak="false">AdditiveExpr</code> is more specific.)</p><div2 id="streamability-guarantees"><head>Streamability Guarantees</head><changes><change issue="2476">A processor is no longer required to report all cases where constructs
              are declared streamable but are not guaranteed streamable according to the streamability
              rules in this specification: that is, processors are free to implement streamability rules
              that are more liberal than those defined here.</change></changes><p>Certain constructs allow a stylesheet author to declare that a construct is
               streamable. Specifically:</p><ulist><item><p>Specifying <code nobreak="false">streamable="yes"</code> on <elcode>xsl:mode</elcode> declares
                     that all template rules in that mode (and all
                        template rules that specify <code nobreak="false">mode="#all"</code>) are
                     streamable;</p></item><item><p>Specifying <code nobreak="false">streamable="yes"</code> on 
                     <elcode>xsl:source-document</elcode> declares that its
                     contained sequence constructor is streamable;</p></item><item><p>Specifying <code nobreak="false">streamable="yes"</code> on <elcode>xsl:function</elcode>
                     declares that the <xtermref spec="XT40" ref="dt-stylesheet-function"/> in question is
                     streamable;</p></item><item><p>Specifying <code nobreak="false">streamable="yes"</code> on <elcode>xsl:attribute-set</elcode>
                     declares that the attribute set in question is streamable;</p></item><item><p>Specifying <code nobreak="false">streamable="yes"</code> 
                     (explicitly or implicitly) on <elcode>xsl:merge-source</elcode> declares
                     that the merging process is streamable with respect to that particular input.</p></item><item><p>Specifying <code nobreak="false">streamable="yes"</code> on <elcode>xsl:accumulator</elcode>
                     declares that the accumulator can be evaluated on a streamed document.</p></item></ulist><p><termdef id="dt-declared-streamable" term="declared-streamable">The above constructs (template rules belonging to a
                  mode declared with <code nobreak="false">streamable="yes"</code>; and <elcode>xsl:source-document</elcode>,
                     <elcode>xsl:attribute-set</elcode>, <elcode>xsl:function</elcode>,
               <elcode>xsl:merge-source</elcode>, and <elcode>xsl:accumulator</elcode>  elements specifying
                     <code nobreak="false">streamable="yes"</code>) are said to be
                  <term>declared-streamable</term>.</termdef></p><p>In each case the construct in question is said to be
                  <term>guaranteed-streamable</term> if it satisfies two conditions:</p><olist><item><p>The construct is <termref def="dt-declared-streamable"/>.</p></item><item><p>Streamability analysis following the rules defined in this specification
                     determines that streamed processing is possible (the detailed conditions vary
                     from one construct to another).</p></item></olist><p><termdef id="dt-guaranteed-streamable" term="guaranteed-streamable">A
                     <term>guaranteed-streamable</term> construct is a <termref def="dt-construct">construct</termref> 
                  that is declared to be streamable and that follows the
                  particular rules for that construct to make streaming possible, as defined by the
                  analysis in this specification.</termdef></p><p>For a streaming processor, that is, a processor that claims conformance with the
                  <termref def="dt-streaming-feature"/>:</p><olist><item><p>If a construct is <termref def="dt-guaranteed-streamable"/> and
                  the input is provided in streamable form, then the input <rfc2119>must</rfc2119> be processed using streaming.</p><note><p>The requirement to process the input using streaming
                  does not apply if the processor is able to determine that this would convey no benefit:
                  for example, if the input is supplied as a tree in memory, or if it can be established
                  in advance that the input file is small.</p></note></item><item><p>If a construct is declared as streamable but is not <termref def="dt-guaranteed-streamable"/> (that is, if it fails to satisfy the
                     conditions for streamability defined in this specification), then the processor
                        <rfc2119>must</rfc2119> be prepared to do any one of the following at user
                     option:</p><olist><!--<item>
                        <p>Raise a static error <errorref spec="XT" class="SE" code="3430"/></p>
                     </item>--><item><p>Process the stylesheet as if it were a non-streaming processor (see
                           below)</p></item><item><p>Process the stylesheet with streaming if it is able to do so, or raise a
                           static error <errorref spec="XT" class="SE" code="3430"/> if it is not
                           able to do so.</p></item></olist></item></olist><p><error spec="XT" type="static" class="SE" code="3430"><p>It is a <xtermref spec="XT40" ref="dt-static-error"/> if a 
                     <xtermref spec="XT40" ref="dt-package">package</xtermref> contains a construct that is
                     declared to be streamable but which is not <termref def="dt-guaranteed-streamable"/>.
                  A processor is not required to report this error if it is capable of processing
                  the stylesheet using streaming.</p></error></p><note><p>In XSLT 3.0, processors were required to have the capability to report an error in all cases
                   where a construct was <termref def="dt-declared-streamable"/> but not 
                   <termref def="dt-guaranteed-streamable"/>, thus effectively
                   inhibiting a processor from implementing extensions to the streamability rules (for example,
                   extensions to take advantage of schema knowledge). This requirement has been dropped in 4.0.
                   All conformant streaming processors are required to evaluate a <termref def="dt-guaranteed-streamable"/>
                   stylesheet in streaming mode, but they are no longer required to detect all stylesheets that are
                   not <termref def="dt-guaranteed-streamable"/>.
                </p></note><p>For a non-streaming processor, the processor <rfc2119>must</rfc2119> evaluate the construct
               delivering the same results as if execution used streaming, but with no constraints
               on the evaluation strategy. (Processing <rfc2119>may</rfc2119>, of
               course, fail due to insufficient memory being available, or for other reasons.)
                  A non-streaming processor is <rfc2119>not
                     required</rfc2119> to assess whether constructs are <termref def="dt-guaranteed-streamable"/>, or to apply restrictions such as the rules
                  for where calls on the functions <function>accumulator-before</function> and
                     <function>accumulator-after</function> may appear. However, a non-streaming
                  processor <rfc2119>must</rfc2119> enforce the constraint implied by a
                     <code nobreak="false">use-accumulators</code> attribute restricting which accumulators can be
                  used with a particular document.</p><note><p>This specification does not attempt to legislate precisely what constitutes
                  evaluation “using streaming”. The most important test is that the amount of memory
                  needed should be for practical purposes independent of the size of the source
                  document, and in particular that the finite size of memory available should not
                  impose a limit on the size of source document that can be processed.</p><p>The rules are designed to ensure that streaming processors can analyze
                  streamability using rules different from those in this specification, provided
                  that all constructs that are <termref def="dt-guaranteed-streamable"/> according
                  to this specification are actually streamable by the implementation. Furthermore,
                  non-streaming processors are not required to analyze streamability at all.</p></note></div2><div2 id="operand-roles"><head>Operand Roles</head><p><termdef id="dt-operand-role" term="operand role">For every construct kind, there is a
               set of zero or more <term>operand roles</term>.</termdef> For example, an
               <code nobreak="false">AdditiveExpr</code> has two operand roles, referred to as the left-hand operand
            and the right-hand operand, while an <code nobreak="false">IfExpr</code> has three, referred to as the
            condition, the then-clause, and the else-clause. A function call with three arguments
            has three operand roles, called the first, second, and third arguments. The names of the
            operand roles for each construct kind are not formally listed, but should be clear from
            the context.</p><p><termdef id="dt-operand" term="operand">In an actual instance of a construct, there will
               be a number of <term>operands</term>. Each operand is itself a <termref def="dt-construct"/>; the construct tree can be defined as the transitive relation
            between constructs and their operands.</termdef> Each operand is associated with exactly one of
            the operand roles for the construct type. There may be operand roles where the operand
            is optional (for example, the <code nobreak="false">separator</code> attribute of the
               <elcode>xsl:value-of</elcode> instruction), and there may be operand roles that can
            be occupied by multiple operands (for example, the <code nobreak="false">xsl:when/@test</code> condition
            in <elcode>xsl:choose</elcode>, or the arguments of the <xfunction>concat</xfunction>
            function).</p><p>Operand roles have a number of properties used in the analysis:</p><ulist><item><p>The <xtermref spec="XT40" ref="dt-required-type"/> of the <termref def="dt-operand"/>. This is
                  explicit in the case of function calls (the required type is defined in the
                  function signature of the corresponding function). In other cases it is implicit
                  in the detailed rules for the construct in question. In practice streamability
                  analysis makes only modest use of the required type; the main case where it is
                  relevant is for a function or template call, where knowing that the required type
                  is atomic enables the inference that the <termref def="dt-operand-usage"/> for a
                  supplied node is <termref def="dt-absorption"/>.</p></item><item><p><termdef id="dt-operand-usage" term="operand usage">The <term>operand
                     usage</term>. This gives information, in the case where the operand value
                     contains nodes, about how those nodes are used. The operand usage takes one of
                     the values <termref def="dt-absorption"/>, <termref def="dt-inspection"/>,
                        <termref def="dt-transmission"/>, or <termref def="dt-navigation"/>.</termdef>
                  The meanings of these terms are explained in <specref ref="operand-roles"/>. 
                 If the required type of the <termref def="dt-operand"/>
                  does not permit nodes to be supplied (for example
                     because the required type is a function item or a map), then the
                  operand usage is <termref def="dt-inspection"/>, because the only run-time
                  operation on a supplied node will be to inspect it, discover it is a node, and
                  raise a type error.</p><p>In the particular case where the required type is atomic, and any supplied nodes
                  are atomized, the operand usage will be <termref def="dt-absorption"/>, because
                     <xtermref spec="XT40" ref="dt-atomization"/> is a special case of absorption.</p></item><item><p><termdef id="dt-higher-order-operand" term="higher-order operand">Whether or not
                     the <termref def="dt-operand"/> is <term>higher-order</term>. For this purpose
                     an operand <var>O</var> of a construct <var>C</var> is higher-order if the
                     semantics of <var>C</var> potentially require <var>O</var> to be evaluated more
                     than once during a single evaluation of <var>C</var>.</termdef> More
                  specifically, <var>O</var> is a <term>higher-order</term> operand of <var>C</var>
                  if any of the following conditions is true:</p><ulist><item><p>The <xtermref spec="XT40" ref="dt-context-item"/> for evaluation of <var>O</var> is
                        different from the context item for evaluation of <var>C</var>.</p></item><item><p><var>C</var> is an <xtermref spec="XT40" ref="dt-instruction"/> and <var>O</var> is a
                           <xtermref spec="XT40" ref="dt-pattern"/> (as with the <code nobreak="false">from</code> and
                           <code nobreak="false">count</code> attributes of <elcode>xsl:number</elcode>, and the
                           <code nobreak="false">group-starting-with</code> and <code nobreak="false">group-ending-with</code>
                        attributes of <elcode>xsl:for-each-group</elcode>).</p></item><item><p><var>C</var> is an XPath <code nobreak="false">for</code>, <code nobreak="false">some</code>, or
                           <code nobreak="false">every</code> expression and <var>O</var> is the expression in its
                           <code nobreak="false">return</code> or <code nobreak="false">satisfies</code> clause.</p></item><item><p><var>C</var> is an inline function declaration and <var>O</var> is the
                        expression in its body.</p></item></ulist></item></ulist><note><p>There is one known case where this definition makes
         an operand higher-order even though it is only evaluated once: specifically, the sequence
         constructor contained in the body of an <elcode>xsl:copy</elcode> instruction that has a 
            <code nobreak="false">select</code> attribute. See <specref ref="streamability-xsl-copy"/> for further details.</p></note></div2><div2 id="operand-usage"><head>Operand Usage</head><p>An <termref def="dt-operand-role"/> gives information about the <termref def="dt-operand">operands</termref> of a particular kind of construct. The two
               important properties of an operand role are the required type and the operand
               usage.</p><p>The <termref def="dt-operand-usage">usage</termref> of an operand role is relevant
               only when the value of an <termref def="dt-operand"/> supplied in that role is a
               node, or a sequence that contains nodes. It is one of the following:</p><ulist><item><p><termdef id="dt-absorption" term="absorption">An operand usage of
                           <term>absorption</term> indicates that the construct reads the subtree(s)
                        rooted at a supplied node(s).</termdef> Examples are constructs that atomize
                     their <termref def="dt-operand">operands</termref>, or that obtain the string
                     value of a supplied node, or that copy the supplied node to a new tree. Another
                     example is the <xfunction>deep-equal</xfunction> function, which compares the
                     subtrees rooted at the nodes supplied in its first two arguments.</p></item><item><p><termdef id="dt-inspection" term="inspection">An operand usage of
                           <term>inspection</term> indicates that the construct accesses properties
                        of a supplied node that are available without reading its subtree.</termdef>
                     Examples are functions such as <xfunction>name</xfunction> and
                        <xfunction>base-uri</xfunction>, and the <code nobreak="false">instance of</code> expression
                     which tests the type of a node (or other item), or functions such as
                        <xfunction>count</xfunction>, <xfunction>exists</xfunction>, and
                        <xfunction>boolean</xfunction> which are only interested in the existence of
                     the node, and not in its properties.</p></item><item><p><termdef id="dt-transmission" term="transmission">An operand usage of
                           <term>transmission</term> indicates that the construct will (potentially)
                        return a supplied node as part of its result to the calling construct (that
                        is, to its parent in the construct tree).</termdef> It also indicates that
                     document order is preserved: if the input is in document order, then the result
                     must be in document order. An example is a filter expression, where nodes in
                     the base expression (the expression being filtered) will typically appear in
                     the result of the filter expression, in their original order.</p></item><item><p><termdef id="dt-navigation" term="navigation">An operand usage of
                           <term>navigation</term> indicates that the construct may navigate freely
                        from the supplied node to other nodes in the same tree, in a way that is not
                        constrained by the streamability rules.</termdef> This covers several cases:
                     cases where it is known that the construct performs impermissible navigation
                     (for example, the <elcode>xsl:number</elcode> instruction) or reordering (the
                        <xfunction>reverse</xfunction> function), or that require look-ahead (the
                        <xfunction>innermost</xfunction> function) and also cases where the analysis
                     is unable to determine what use is made of the node, for example because it is
                     passed as an argument to a user-defined function, or retained in a
                     variable.</p></item></ulist><p>The concept of operand usage is not used for all
                  constructs (for example, it is not used in the analysis of path expressions).
                  Where it is used, the assignment of operand usages to each operand role
               of a construct is defined in the relevant subsection of
              <specref ref="streamability-of-constructs"/>.</p><div3 id="type-determined-usage"><head>Type-determined Usage</head><p><termdef id="dt-type-determined-usage" term="type-determined usage">The
                  <term>type-determined usage</term> of an <termref def="dt-operand"/> is as
               follows: if the required type (ignoring occurrence indicator) is
                  <code nobreak="false">fn(*)</code> or a subtype thereof, then <termref def="dt-inspection"/>; if the required type (ignoring occurrence indicator) is an atomic or union type, then <termref def="dt-absorption"/>; otherwise <termref def="dt-navigation"/>.</termdef></p><p><termdef id="dt-type-adjusted-posture-and-sweep" term="type-adjusted posture and sweep">The <term>type-adjusted posture and
                  sweep</term> of a construct <var>C</var>, with respect to a type <var>T</var>, are
               the <termref def="dt-posture"/> and <termref def="dt-sweep"/> established by applying
               the <termref def="dt-general-streamability-rules"/> to a construct <var>D</var> whose
               single operand is the construct <var>C</var>, where the <termref def="dt-operand-usage"/> of <var>C</var> in <var>D</var> is the <termref def="dt-type-determined-usage"/> based on the required type
               <var>T</var>.</termdef></p><note><p>In effect, the type-adjusted posture and sweep are the posture and sweep of the
               implicit expression formed to apply the <xtermref spec="XT40" ref="dt-coercion-rules"/>
               to the argument of a function or template call, or to the result of a function or
               template, given knowledge of the required type. For example, an expression such as
                  <code nobreak="false">discount</code> in the function call <code nobreak="false">abs(discount)</code>, which would
               otherwise be <termref def="dt-striding"/> and <termref def="dt-consuming"/>, becomes
                  <termref def="dt-grounded"/> and <termref def="dt-consuming"/> because of the
               implicit atomization triggered by the coercion rules.</p></note></div3></div2><div2 id="streamability-properties"><head>Streamability Properties</head><p>The process of determining whether a construct is streamable reduces to determining
            properties of the constructs in the construct tree. The properties in question (which
            are described in greater detail in subsequent sections) are:</p><olist><item><p>The <term>static type</term> of the construct. When the construct is evaluated,
                  its value will always be an instance of this type. The value is a <termref def="dt-utype"/>; although type
                  inferencing is capable of determining information about the cardinality as well as
                  the item type, the streamability analysis makes no use of this.</p></item><item><p>The <term>context item type</term>: that is, the static type of the <xtermref spec="XT40" ref="dt-context-item"/> potentially used as input to the construct. When the
                  construct is evaluated, the context item used to evaluate the construct (if it is
                  used at all) will be an instance of this type.</p></item><item><p><termdef id="dt-posture" term="posture">The <term>posture</term> of the
                     expression. This captures information about the way in which the streamed input
                     document is positioned on return from evaluating the construct. The posture
                     takes one of the values <termref def="dt-climbing"/>, <termref def="dt-striding"/>, <termref def="dt-crawling"/>, <termref def="dt-roaming"/>, or <termref def="dt-grounded"/>.</termdef> The meanings of these terms are
                  explained in <specref ref="posture"/>.</p></item><item><p><termdef id="dt-context-posture" term="context posture">The <term>context
                        posture</term>. This captures information about how the <xtermref spec="XT40" ref="dt-context-item"/> used as input to the construct is positioned
                     relative to the streamed input. The <term>context posture</term> of a construct
                     C is the posture of the expression whose value sets the focus for the
                     evaluation of C.</termdef> Rules for determining the
                     context posture of any construct are given in <specref ref="determining-context-posture"/>.</p></item><item><p>The <term>sweep</term> of the construct. The sweep of a construct gives
                  information about whether and how the evaluation of the construct changes the
                  current position in a streamed input document. The possible values are <termref def="dt-motionless"/>, <termref def="dt-consuming"/>, and <termref def="dt-free-ranging"/>. These terms are explained in <specref ref="sweep"/>.</p></item></olist><p>The values of these properties for a top-level construct such as the body of a template
            rule determine whether the construct is streamable.</p><p>The values of these properties are not independent. For example, if the static type is
            atomic, then the posture will always be grounded; if the sweep is free-ranging, then the
            posture will always be roaming.</p><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of a
               <termref def="dt-construct"/>, as defined above, are calculated in relation to a
            particular streamed input document. If there is more than one streamed input document,
            then a construct that is motionless with respect to one streamed input might be
            consuming with respect to another. In practice, though, the streamability analysis is
            only ever concerned with one particular streamed input at a time; constructs are
            analyzed in relation to the innermost containing <elcode>xsl:template</elcode>,
               <elcode>xsl:source-document</elcode>, <elcode>xsl:accumulator</elcode>, or
               <elcode>xsl:merge-source</elcode> element, and this container implicitly defines the
            streamed input document that is relevant. The streamed input document affecting a
            construct is always the document that contains the context item for evaluation of that
               construct.</p></div2><div2 id="determining-static-type"><head>Determining the Static Type of a Construct</head><changes><change PR="2011" issue="675" date="2025-05-18">
                  The static typing rules have been updated to take account of new constructs in XPath 4.0.
               </change></changes><p><termdef id="dt-static-type" term="static type">The <term>static type</term> of a
                     <termref def="dt-construct">construct</termref> is such that all values
                  produced by evaluating the construct will conform to that type. The static type of
                  a construct comprises a <termref def="dt-utype"/> and a cardinality.
                  A cardinality is a range of integers (from <code nobreak="false">min</code> to <code nobreak="false">max</code>).</termdef></p><p><termdef id="dt-utype" term="U-type">A <term>U-type</term> is a set of <termref def="dt-fundamental-item-type">fundamental item types</termref>.</termdef></p><p><termdef id="dt-fundamental-item-type" term="fundamental item type">There are 29
                     <term>fundamental item types</term>: the 7 node kinds defined in <bibref ref="xpath-datamodel-40"/> (element, attribute, etc.), the 19 primitive atomic
                  types defined in <bibref ref="xmlschema-2"/>, plus the types
                     <code nobreak="false">fn(*)</code>, <code nobreak="false">xs:untypedAtomic</code>, and <code nobreak="false">JNode</code>. The fundamental
                  item types are disjoint, and every item is an instance of exactly one of
                  them.</termdef></p><p>More specifically, the fundamental item types are:</p><ulist><item><p><code nobreak="false">document-node()</code>, <code nobreak="false">element()</code>, <code nobreak="false">attribute()</code>,
                        <code nobreak="false">text()</code>, <code nobreak="false">comment()</code>,
                        <code nobreak="false">processing-instruction()</code>, <code nobreak="false">namespace-node()</code>;</p></item><item><p><code nobreak="false">xs:boolean</code>, <code nobreak="false">xs:double</code>, <code nobreak="false">xs:decimal</code>,
                        <code nobreak="false">xs:float</code>, <code nobreak="false">xs:string</code>, <code nobreak="false">xs:dateTime</code>,
                        <code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>, <code nobreak="false">xs:gYear</code>,
                        <code nobreak="false">xs:gYearMonth</code>, <code nobreak="false">xs:gMonth</code>,
                        <code nobreak="false">xs:gMonthDay</code>, <code nobreak="false">xs:gDay</code>, <code nobreak="false">xs:anyURI</code>,
                        <code nobreak="false">xs:QName</code>, <code nobreak="false">xs:NOTATION</code>,
                        <code nobreak="false">xs:base64Binary</code>, <code nobreak="false">xs:hexBinary</code>,
                        <code nobreak="false">xs:duration</code></p></item><item><p><code nobreak="false">fn(*)</code></p></item><item><p><code nobreak="false">xs:untypedAtomic</code></p></item><item><p><code nobreak="false">JNode</code></p></item></ulist><p>TODO: extend the analysis to include JNodes.</p><p>A value <var>V</var> (in general, a sequence) is an instance of a <termref def="dt-utype"/>
               <var>U</var> if every item in <var>V</var> is an instance of one of the <termref def="dt-fundamental-item-type">fundamental item types</termref> in <var>U</var>.
               For example, the sequence <code nobreak="false">(23, "Paris")</code> is an instance of the U-type
                  <code nobreak="false">U{xs:string, xs:decimal, xs:date}</code> because both items in the sequence
               belong to item types in this U-type. </p><note><p>It is a consequence of this rule that the empty sequence, <code nobreak="false">()</code>, is an
                  instance of every U-type.</p></note><p>A <termref def="dt-utype"/> is represented in this specification using the notation
                  <var>U{t1, t2, t3, ...}</var> where <code nobreak="false">t1, t2, t3, ...</code> are the names of
               the fundamental item types making up the U-type. The item types are represented using
               the syntax of the <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XP40" ref="prod-xpath40-ItemType" xlink:type="simple">ItemType</xnt>
               production in XPath, for example <code nobreak="false">comment()</code> or <code nobreak="false">xs:date</code>.</p><note><p>This means that the order of <code nobreak="false">t1, t2, t3, ...</code> has no significance:
                     <var>U{A, B}</var> is the same U-type as <var>U{B, A}</var>.</p></note><p>The smallest U-type is denoted <var>U{}</var>. This is not an empty type; like every
               other U-type, it has the empty sequence <code nobreak="false">()</code> as an instance. For
               convenience, the universal U-type is represented as <var>U{*}</var>; the U-type
               corresponding to the set of 7 node kinds is written <var>U{N}</var>, and the U-type
               corresponding to all atomic items (that is, the 19 primitive atomic types plus
                  <code nobreak="false">xs:untypedAtomic</code>) is written <var>U{A}</var>.</p><p>Because a <termref def="dt-utype"/> is a set, the operations of union, intersection,
               and difference are defined over U-types, and the result is always a U-type. If one
               U-type <var>U</var> is a subset of another U-type <var>V</var>, then <var>U</var> is
               said to be a subtype of <var>V</var>, and <var>V</var> is said to be a supertype of
                  <var>U</var>.</p><p>In some cases the inference of a <termref def="dt-static-type"/> depends on the
               declared types of variables or functions. Since declared types use the
               <xtermref spec="XT40" ref="dt-sequence-type"/> 
               syntax, there is therefore a mapping defined from
               SequenceTypes to U-types. The mapping is as follows:</p><ulist><item><p>The <xtermref spec="XT40" ref="dt-sequence-type"/> 
                     <code nobreak="false">empty-sequence()</code> maps to <var>U{}</var></p></item><item><p>For every other <xtermref spec="XT40" ref="dt-sequence-type"/>, 
                     the mapping depends only on the item type and
                     ignores the occurrence indicator. The mapping from item types is as
                     follows:</p><ulist><item><p><code nobreak="false">item()</code> maps to <var>U{*}</var></p></item><item><p>A choice item type <code nobreak="false">(A | B | C)</code> maps
                        to the union of the U-types corresponding to <code nobreak="false">A</code>,
                        <code nobreak="false">B</code>, and <code nobreak="false">C</code>.</p></item><item><p><code nobreak="false">AnyKindTest</code> (<code nobreak="false">node()</code>) maps to
                           <var>U{N}</var></p></item><item><p><code nobreak="false">DocumentTest</code> maps to <var>U{document-node()}</var></p></item><item><p><code nobreak="false">ElementTest</code> and <code nobreak="false">SchemaElementTest</code> map to
                              <var>U{element()}</var></p></item><item><p><code nobreak="false">AttributeTest</code> and <code nobreak="false">SchemaAttributeTest</code> map to
                              <var>U{attribute()}</var></p></item><item><p><code nobreak="false">TextTest</code> maps to <var>U{text()}</var></p></item><item><p><code nobreak="false">CommentTest</code> maps to <var>U{comment()}</var></p></item><item><p><code nobreak="false">PITest</code> maps to <var>U{processing-instruction()}</var></p></item><item><p><code nobreak="false">NamespaceNodeTest</code> maps to <var>U{namespace-node()}</var></p></item><item><p><code nobreak="false">FunctionType</code>, <code nobreak="false">MapType</code>, 
                           and <code nobreak="false">ArrayType</code> and <code nobreak="false">RecordType</code> 
                           map to <var>U{fn(*)}</var></p></item><item><p>The QName <code nobreak="false">xs:error</code> maps to <var>U{}</var></p></item><item><p>A QName <var>Q</var> representing an atomic type that is a fundamental
                           item type maps to <var>U{Q}</var></p></item><item><p>A QName <var>Q</var> representing an atomic type derived from a
                           fundamental item type <var>F</var> maps to <var>U{F}</var></p></item><item><p>A QName <var>Q</var> representing a pure union type maps to a U-type
                           containing the fundamental item types present in the transitive
                           membership of the union, or from which the transitive members of the
                           union are derived.</p></item></ulist></item></ulist><div3 id="static-type-of-xpath-expressions"><head>Static Type Inference for XPath Expressions</head><p>Although all constructs have a <termref def="dt-static-type"/>, the streamability
               analysis only needs to know the static type of XPath expressions, so the rules here
               are largely confined to that case. For <xtermref spec="XT40" ref="dt-pattern">patterns</xtermref>, the <termref def="dt-static-type"/> is
                  deemed to be <var>U{xs:boolean}</var>, reflecting the fact that a pattern is
                  essentially a function that can be applied to items to deliver a <code nobreak="false">true</code> or <code nobreak="false">false</code>
                  (matching or non-matching) result.
               For constructs other than <xtermref spec="XT40" ref="dt-expression">expressions</xtermref>
                  and <xtermref spec="XT40" ref="dt-pattern">patterns</xtermref>, the <termref def="dt-static-type"/> for the
                  purpose of streamability analysis is taken as <var>U{*}</var>.</p><p>The rules given here are deliberately simple. Implementations may well be able to
               compute a more precise <termref def="dt-static-type"/>, but this will rarely be
               useful for streamability analysis. The item type for each kind of XPath expression is
               determined by the rules below. The columns are interpreted as follows:</p><ulist><item><p>The name in the first column is the name of a production
               in the XPath grammar.</p></item><item><p>In the
                  second column, the <term>Proforma</term> uses an informal notation used both to
                  provide a reminder of the syntax of the construct in question, and to attach
                  labels to its operand roles so that they can be referred to in the text of the
                  third column.</p></item><item><p>The third column gives the static type of the expression, either as
               a <termref def="dt-utype"/>, or as a formula for computing the U-type. In these
               formulae, <code nobreak="false">T(<var>E</var>)</code> means the U-type of expression <var>E</var>,
               <code nobreak="false"><var>U1</var>|<var>U2</var></code> means the union of U-types <var>U1</var>
               and <var>U2</var>, and <code nobreak="false"><var>U1</var> intersect <var>U2</var></code> means the intersection of U-types <var>U1</var>
               and <var>U2</var>.</p></item><item><p>The fourth column gives the cardinality of the result, either as an explicit range, or
                  as a formula. For example
               (0, 1) indicates a cardinality range from zero to one inclusive. <var>N</var> represents
               unbounded cardinality. The notation <code nobreak="false">C(<var>E</var>)</code> represents the cardinality
               of expression <var>E</var>.</p><p>The sum of two cardinalities <code nobreak="false"><var>C</var> + <var>D</var></code> is the range
                  <code nobreak="false">(<var>C/min</var>+<var>D/min</var>, <var>C/max</var>+<var>D/max</var>)</code>.</p><p>The product of two cardinalities <code nobreak="false"><var>C</var> * <var>D</var></code> is the range
                  <code nobreak="false">(<var>C/min</var>*<var>D/min</var>, <var>C/max</var>*<var>D/max</var>)</code>.</p><p>The maximum of two cardinalities <code nobreak="false">max(<var>C</var>, <var>D</var>)</code> is the range
                  <code nobreak="false">(<var>min(C/min</var>, <var>D/min</var>), max(<var>C/max</var>, <var>D/max</var>))</code>.</p></item></ulist><table class="data"><caption>Inferring a Static Type for XPath 3.0 Expressions</caption><thead><tr><th rowspan="1" colspan="1">Construct</th><th rowspan="1" colspan="1">Proforma</th><th rowspan="1" colspan="1">Static Item Type</th><th rowspan="1" colspan="1">Cardinality</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">Expr</td><td rowspan="1" colspan="1"><code nobreak="false">E,F</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(E) | T(F)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(E) + C(F)</code></td></tr><tr><td rowspan="1" colspan="1">ForExpr</td><td rowspan="1" colspan="1"><code nobreak="false">for $x in S return E</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(E)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(S) * C(E)</code></td></tr><tr><td rowspan="1" colspan="1">LetExpr</td><td rowspan="1" colspan="1"><code nobreak="false">let $x := S return E</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(E)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(E)</code></td></tr><tr><td rowspan="1" colspan="1">QuantifiedExpr</td><td rowspan="1" colspan="1"><code nobreak="false">some|every $x in S satisfies C</code></td><td rowspan="1" colspan="1"><var>U{xs:boolean}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="2" colspan="1">IfExpr</td><td rowspan="1" colspan="1"><code nobreak="false">if (C) then A else B</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(A) | T(B)</code></td><td rowspan="1" colspan="1"><code nobreak="false">max(C(A), C(B))</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">if (C) { A }</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(A)</code></td><td rowspan="1" colspan="1"><code nobreak="false">max(C(A), (0,0))</code></td></tr><tr><td rowspan="1" colspan="1">OtherwiseExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A otherwise B</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(A) | T(B)</code></td><td rowspan="1" colspan="1"><code nobreak="false">max(C(A), C(B))</code></td></tr><tr><td rowspan="1" colspan="1">OrExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E or F</code></td><td rowspan="1" colspan="1"><var>U{xs:boolean}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">AndExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E and F</code></td><td rowspan="1" colspan="1"><var>U{xs:boolean}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">ComparisonExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E = F</code>; <code nobreak="false">E eq F</code>; <code nobreak="false">E is F</code></td><td rowspan="1" colspan="1"><var>U{xs:boolean}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(0,1)</code></td></tr><tr><td rowspan="1" colspan="1">StringConcatExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E || F</code></td><td rowspan="1" colspan="1"><var>U{xs:string}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">RangeExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E to F</code></td><td rowspan="1" colspan="1"><var>U{xs:decimal}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1">AdditiveExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E + F</code></td><td rowspan="1" colspan="1"><var>U{A}</var>. But if the expression
                           is a predicate (that is, if it appears between square brackets in a
                           filter expression or axis step), then <var>U{xs:decimal, xs:double,
                              xs:float}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(0,1)</code></td></tr><tr><td rowspan="1" colspan="1">MultiplicativeExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E * F</code></td><td rowspan="1" colspan="1"><var>U{A}</var>. But if the expression
                           is a predicate (that is, if it appears between square brackets in a
                           filter expression or axis step), then <var>U{xs:decimal, xs:double,
                              xs:float}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(0,1)</code></td></tr><tr><td rowspan="1" colspan="1">UnionExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A | B</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(A) | T(B)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(A) + C(B)</code></td></tr><tr><td rowspan="2" colspan="1">IntersectExceptExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A intersect B</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(A) intersect T(B)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(A) * (0,1)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">E except F</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(A)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(A) * (0,1)</code></td></tr><tr><td rowspan="1" colspan="1">InstanceOfExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E instance of T</code></td><td rowspan="1" colspan="1"><var>U{xs:boolean}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">TreatExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E treat as T</code></td><td rowspan="1" colspan="1">The U-type corresponding to the SequenceType T</td><td rowspan="1" colspan="1">The cardinality of the SequenceType T</td></tr><tr><td rowspan="1" colspan="1">CastableExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E castable as T</code></td><td rowspan="1" colspan="1"><var>U{xs:boolean}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">CastExpr</td><td rowspan="1" colspan="1"><code nobreak="false">E cast as T</code></td><td rowspan="1" colspan="1">if T is an atomic or pure union type, the corresponding U-type. Otherwise,
                        for example if T is a list type, <var>U{A}</var>.</td><td rowspan="1" colspan="1">if T is an atomic or pure union type, (0,1). Otherwise,
                        for example if T is a list type, (0,N).</td></tr><tr><td rowspan="1" colspan="1">UnaryExpr</td><td rowspan="1" colspan="1"><code nobreak="false">-N</code></td><td rowspan="1" colspan="1"><var>U{xs:decimal, xs:double, xs:float}</var></td><td rowspan="1" colspan="1"><code nobreak="false">C(N)</code></td></tr><tr><td rowspan="1" colspan="1">SimpleMapExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A ! B</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(B)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(A) * C(B)</code></td></tr><tr><td rowspan="3" colspan="1">PathExpr</td><td rowspan="1" colspan="1"><code nobreak="false">/</code></td><td rowspan="1" colspan="1"><var>U{document-node()}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">/P</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(P)</code></td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">//P</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(P)</code></td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1">RelativePathExpr</td><td rowspan="1" colspan="1"><code nobreak="false">P/Q</code>; <code nobreak="false">P//Q</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(Q)</code></td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1">AxisStep</td><td rowspan="1" colspan="1"><code nobreak="false">E[P]</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(E)</code>: see <specref ref="static-type-of-steps"/></td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1">ForwardStep, ReverseStep</td><td rowspan="1" colspan="1"><code nobreak="false">Axis::NodeTest</code></td><td rowspan="1" colspan="1">See <specref ref="static-type-of-steps"/></td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="3" colspan="1">PostfixExpr</td><td rowspan="1" colspan="1">FilterExpr <code nobreak="false">E[P]</code></td><td rowspan="1" colspan="1">the static type of E</td><td rowspan="1" colspan="1">If <code nobreak="false">P</code> is numeric with max cardinality 1, 
                        then <code nobreak="false">(0,1)</code>. Otherwise <code nobreak="false">C(E) * (0,1)</code></td></tr><tr><td rowspan="1" colspan="1">FilterExprAM <code nobreak="false">E?[P]</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(E)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(E) * (0,1)</code></td></tr><tr><td rowspan="1" colspan="1">Dynamic Function Call <code nobreak="false">F(X, Y)</code></td><td rowspan="1" colspan="1"><var>U{*}</var>, unless ancillary information is available about the
                        function signature of F: see below.</td><td rowspan="1" colspan="1">The cardinality of the return type of <code nobreak="false">F</code>.</td></tr><tr><td rowspan="1" colspan="1">Literal</td><td rowspan="1" colspan="1"><code nobreak="false">"pH"</code>, <code nobreak="false">93.7</code>, <code nobreak="false">#xml:space</code></td><td rowspan="1" colspan="1"><var>U{xs:string}</var>, <var>U{xs:decimal}</var>, 
                           <var>U{xs:double}</var>, or <var>U{xs:QName}</var> depending on the form of the literal</td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">StringTemplate</td><td rowspan="1" colspan="1"><code nobreak="false">`{$x}{$y}`</code></td><td rowspan="1" colspan="1"><var>U{xs:string}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">VarRef</td><td rowspan="1" colspan="1"><code nobreak="false">$V</code></td><td rowspan="1" colspan="1">The declared type of the variable if declared,
                        otherwise the item type of the expression to which the variable is bound.</td><td rowspan="1" colspan="1">The declared cardinality of the variable if declared,
                        otherwise the cardinality of the expression to which the variable is bound,
                        or <code nobreak="false">(1,1)</code> in the case of a variable declared in a <code nobreak="false">ForExpr</code>
                        or <code nobreak="false">QuantifiedExpr</code>.</td></tr><tr><td rowspan="2" colspan="1">ParenthesizedExpr</td><td rowspan="1" colspan="1"><code nobreak="false">(E)</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(E)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(E)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">()</code></td><td rowspan="1" colspan="1"><var>U{}</var> (a type whose only instance is the empty sequence)</td><td rowspan="1" colspan="1"><code nobreak="false">(0,0)</code></td></tr><tr><td rowspan="1" colspan="1">ContextValueRef</td><td rowspan="1" colspan="1"><code nobreak="false">.</code></td><td rowspan="1" colspan="1">the context item type: see below</td><td rowspan="1" colspan="1">the context cardinality: see below</td></tr><tr><td rowspan="1" colspan="1">FunctionCall</td><td rowspan="1" colspan="1"><code nobreak="false">F(X, Y)</code></td><td rowspan="1" colspan="1">In general: the U-type corresponding to
                        the declared result type of function <var>F</var>. But:
                        <ulist><item><p>If one or more of
                              the arguments to the function have operand usage <termref def="dt-transmission"/>, then the intersection of the U-type
                              corresponding to the declared result type with the union of the static
                              types of the arguments having usage transmission. (For example, the
                              static type of the function call <code nobreak="false">head(//text())</code> is
                              <var>U{text()}</var>.)</p></item><item><p>Special rules apply to the
                           <function>current</function> function: see <specref ref="static-type-of-current-function"/>.</p></item></ulist></td><td rowspan="1" colspan="1"><code nobreak="false">TODO</code></td></tr><tr><td rowspan="1" colspan="1">Partial Function Application</td><td rowspan="1" colspan="1"><code nobreak="false">F(X, ?)</code>, $F(X, ?)</td><td rowspan="1" colspan="1"><var>U{fn(*)}</var></td><td rowspan="1" colspan="1"><code nobreak="false">TODO</code></td></tr><tr><td rowspan="1" colspan="1">NamedFunctionRef</td><td rowspan="1" colspan="1"><code nobreak="false">F#n</code></td><td rowspan="1" colspan="1"><var>U{fn(*)}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">InlineFunctionExpr</td><td rowspan="1" colspan="1"><code nobreak="false">fn(P) {E}</code></td><td rowspan="1" colspan="1"><var>U{fn(*)}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">MapConstructor</td><td rowspan="1" colspan="1"><code nobreak="false">{ "A": E, "B": F }</code></td><td rowspan="1" colspan="1"><var>U{fn(*)}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">Postfix Lookup (Shallow)</td><td rowspan="1" colspan="1"><code nobreak="false">E ? K</code></td><td rowspan="1" colspan="1">If the type of <var>E</var> is a map type <code nobreak="false">map(K, V)</code> or an
                        array type <code nobreak="false">array(V)</code>, then the U-type corresponding to the item
                        type of <var>V</var>; otherwise <var>U{*}</var>. An implementation <rfc2119>may</rfc2119>
                     be able to determine a more precise type when the type of <var>E</var> is a record type.</td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1">Unary Lookup (Shallow)</td><td rowspan="1" colspan="1"><code nobreak="false">? K</code></td><td rowspan="1" colspan="1">If the context item type is a map type <code nobreak="false">map(K, V)</code> or an array
                        type <code nobreak="false">array(V)</code>, then the U-type corresponding to the item type
                        of <var>V</var>; otherwise <var>U{*}</var>. An implementation <rfc2119>may</rfc2119>
                     be able to determine a more precise type when the context item type is a record type.</td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1">Deep Lookup</td><td rowspan="1" colspan="1"><code nobreak="false">?? K</code>, <code nobreak="false">E ?? K</code></td><td rowspan="1" colspan="1"><var>U{*}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(0,N)</code></td></tr><tr><td rowspan="1" colspan="1">PipelineExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A -&gt; B</code></td><td rowspan="1" colspan="1"><code nobreak="false">T(B)</code></td><td rowspan="1" colspan="1"><code nobreak="false">C(B)</code></td></tr><tr><td rowspan="1" colspan="1">ArrowExpr</td><td rowspan="1" colspan="1"><code nobreak="false">X =&gt; F(Y, Z)</code>, <code nobreak="false">X =!&gt; F(Y, Z)</code></td><td rowspan="1" colspan="1">The static type of the equivalent static or dynamic function call 
                        <code nobreak="false">F(X, Y, Z)</code></td><td rowspan="1" colspan="1">The cardinality of the equivalent static or dynamic function call 
                        <code nobreak="false">F(X, Y, Z)</code></td></tr><tr><td rowspan="1" colspan="1">SquareArrayConstructor</td><td rowspan="1" colspan="1"><code nobreak="false">[ X, Y, ... ]</code></td><td rowspan="1" colspan="1"><var>U{fn(*)}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr><tr><td rowspan="1" colspan="1">CurlyArrayConstructor</td><td rowspan="1" colspan="1"><code nobreak="false">array {X, Y, ... }</code></td><td rowspan="1" colspan="1"><var>U{fn(*)}</var></td><td rowspan="1" colspan="1"><code nobreak="false">(1,1)</code></td></tr></tbody></table><p>Where the <termref def="dt-static-type"/> of an expression is
                  <var>U{fn(*)}</var>, it is useful to retain additional information:
               specifically, the signature of the function. This may be regarded as information
               ancillary to the U-type of the expression; it does not play any role in operations
               such as testing whether one U-type is a subtype of another, or forming the union of
               two U-types. This ancillary information is available for a
                  <code nobreak="false">NamedFunctionRef</code>, for an <code nobreak="false">InlineFunctionExpr</code>, for a
                  <code nobreak="false">MapConstructor</code>, for a <code nobreak="false">FunctionCall</code> whose static type is
                  <var>U{fn(*)}</var>, and for a <code nobreak="false">VarRef</code> if the variable is bound
               to any of the forgoing, or if it has a declared type corresponding to
                  <var>U{fn(*)}</var>.</p><note><p>The special case type inference used for an <code nobreak="false">AdditiveExpr</code> or
                     <code nobreak="false">MultiplicativeExpr</code> appearing as a predicate is possible because if
                  an arithmetic operation within a predicate produces any other result, for example
                  an <code nobreak="false">xs:duration</code> or <code nobreak="false">xs:dateTime</code>, this would cause a type
                  error (on the grounds that an <code nobreak="false">xs:duration</code> or <code nobreak="false">xs:dateTime</code>
                  has no effective boolean value), and static type inference only needs to consider
                  the type of non-error results. The benefit of this special rule is that filter
                  expressions such as <code nobreak="false">/descendant::section[$i + 1]</code> can be recognized as
                  returning a singleton, and therefore as being <termref def="dt-striding"/>, even
                  if the type of <code nobreak="false">$i</code> is unknown.</p></note></div3><div3 id="static-type-of-steps"><head>Static Type of an Axis Step</head><p>An <code nobreak="false">AxisStep</code> consists of either a <code nobreak="false">ForwardStep</code> or <code nobreak="false">ReverseStep</code>
               followed by zero or more predicates. The predicates have no effect on the inferred type of the
               <code nobreak="false">AxisStep</code>.</p><p>The static type of an abbreviated step is the static type of its expansion, for example the
               static type of <code nobreak="false">@*</code> is the same as the static type of <code nobreak="false">attribute::*</code>.</p><p>Both the constructs <code nobreak="false">ForwardStep</code> or <code nobreak="false">ReverseStep</code>, in their
                  unabbreviated form, are written as <code nobreak="false">Axis::NodeTest</code>. The static type depends
               on both the <code nobreak="false">Axis</code> and the <code nobreak="false">NodeTest</code>, and also on the
                  <termref def="dt-context-item-type"/>, determined as described in 
                 <specref ref="determining-context-item-type"/>.</p><p>If the <termref def="dt-context-item-type"/> has an empty intersection with <code nobreak="false">U{N}</code>
                  (that is, if the context item type cannot be a node), then evaluation of the <code nobreak="false">AxisStep</code>
                  will always fail; it is permissible to raise a type error statically in this case, but for the
                  sake of the analysis, the static type of the <code nobreak="false">AxisStep</code> can be taken as <code nobreak="false">U{}</code>.
                  In other cases, let <var>CIT</var> be the intersection of the <termref def="dt-context-item-type"/>
                   with <code nobreak="false">U{N}</code>.</p><p>Let <var>K(A, CIT)</var> be the set of <term>reachable node kinds</term> given an axis <var>A</var> 
                  (a <termref def="dt-utype"/>) as defined by the following table: </p><table><thead><tr><th rowspan="1" colspan="1">Axis</th><th rowspan="1" colspan="1">Reachable Node Kinds</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">self</td><td rowspan="1" colspan="1"><var>CIT</var></td></tr><tr><td rowspan="1" colspan="1">attribute</td><td rowspan="1" colspan="1">if <var>CIT</var> includes <code nobreak="false">U{element()}</code> then <code nobreak="false">U{attribute()}</code> else <code nobreak="false">U{}</code></td></tr><tr><td rowspan="1" colspan="1">namespace</td><td rowspan="1" colspan="1">if <var>CIT</var> includes <code nobreak="false">U{element()}</code> then <code nobreak="false">U{namespace-node()}</code> else <code nobreak="false">U{}</code></td></tr><tr><td rowspan="1" colspan="1">child, descendant</td><td rowspan="1" colspan="1">if <var>CIT</var> includes <code nobreak="false">U{element()}</code> or <code nobreak="false">U{document-node()}</code> then 
                           <code nobreak="false">U{element(), text(), comment(), processing-instruction()}</code> else <code nobreak="false">U{}</code></td></tr><tr><td rowspan="1" colspan="1">following-sibling, preceding-sibling, following, preceding</td><td rowspan="1" colspan="1">if <var>CIT</var> is <code nobreak="false">U{document-node()}</code> then <code nobreak="false">U{}</code> else
                           <code nobreak="false">U{element(), text(), comment(), processing-instruction()}</code></td></tr><tr><td rowspan="1" colspan="1">parent, ancestor</td><td rowspan="1" colspan="1">if <var>CIT</var> is <code nobreak="false">U{document-node()}</code> then <code nobreak="false">U{}</code> else
                           <code nobreak="false">U{element(), document-node()}</code> </td></tr><tr><td rowspan="1" colspan="1">ancestor-or-self</td><td rowspan="1" colspan="1">the union of <var>K(ancestor, CIT)</var> and <var>CIT</var></td></tr><tr><td rowspan="1" colspan="1">descendant-or-self</td><td rowspan="1" colspan="1">the union of <var>K(descendant, CIT)</var> and <var>CIT</var></td></tr></tbody></table><p>Let <code nobreak="false">T(NT)</code> be the set of node kinds that are capable of satisfying a <code nobreak="false">NodeTest</code> <var>NT</var>,
               defined by the following table:</p><table><thead><tr><th rowspan="1" colspan="1">NodeTest</th><th rowspan="1" colspan="1">Possible Node Kinds</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><code nobreak="false">AnyKindTest</code> (that is, <code nobreak="false">node()</code>)</td><td rowspan="1" colspan="1"><var>U{N}</var> (that is, any node)</td></tr><tr><td rowspan="1" colspan="1">Any other <code nobreak="false">KindTest</code></td><td rowspan="1" colspan="1">The corresponding <termref def="dt-utype"/> (for example, <code nobreak="false">U{text()}</code> 
                           for the <code nobreak="false">KindTest</code> <code nobreak="false">text()</code>)</td></tr><tr><td rowspan="1" colspan="1">NameTest</td><td rowspan="1" colspan="1">The <termref def="dt-utype"/> corresponding to the principal node kind of the
                        specified axis</td></tr></tbody></table><p>The static type of an <code nobreak="false">AxisStep</code> with axis <var>A</var> and node test <code nobreak="false">NT</code>,
                  given a context item type <var>CIT</var>, is then defined to be the 
               intersection of <code nobreak="false">K(A, CIT)</code> with <code nobreak="false">T(NT)</code>.</p></div3><div3 id="static-type-of-current-function"><head>Static Type of a Call to <code nobreak="false">current</code></head><p>The rules in this section define the static type of a call to the <function>current</function>
               function.</p><olist><item><p>If the call is within a <xtermref spec="XT40" ref="dt-pattern"/>, the static type of the function call is the <termref def="dt-match-type"/> of the pattern.</p><note><p>There is no circularity in this definition: a call to <function>current</function> in a pattern can only appear within a predicate, and
                        the match type of a pattern never depends on anything appearing in a predicate.</p></note></item><item><p>Otherwise (the function call is within an XPath expression), the static type of the function call is the
                     <termref def="dt-context-item-type"/> that applies to the outermost containing XPath expression, determined by the rules in 
                     <specref ref="determining-context-item-type"/>.
                  </p></item></olist></div3><div3 id="notes-on-schema-aware-analysis"><head>Schema-Aware Streamability Analysis</head><note><p>The streamability analysis in this chapter is not schema-aware. There are cases
                  where use of schema type information might enable a processor to determine that a
                  construct is streamable when it would be unable to make this determination
                  otherwise. Two examples:</p><ulist><item><p>A processor might decide that a construct such as <code nobreak="false">price +
                           salesTax</code> is streamable if both the child elements have a simple
                        type such as <code nobreak="false">xs:decimal</code>, or if the order in which they appear
                        in the input document is known.</p></item><item><p>A processor might decide that a step using the descendant axis, such as
                           <code nobreak="false">.//title</code>, has <termref def="dt-striding"/> rather than
                           <termref def="dt-crawling"/>
                        <termref def="dt-posture"/> if it can establish that two <code nobreak="false">title</code>
                        elements will never be nested
                        (that is, a <code nobreak="false">title</code> cannot contain another <code nobreak="false">title</code>).
                        This would allow the instruction <code nobreak="false">&lt;xsl:apply-templates
                           select=".//title"/&gt;</code> to be used in a streaming template rule.</p></item></ulist><p>Although such constructs are not guaranteed streamable according to this
                  specification, there is nothing to prevent a processor providing a streamed
                  implementation if it is able to do so.</p></note></div3></div2><div2 id="determining-context-item-type"><head>Determining the Context Item Type</head><p><termdef id="dt-context-item-type" term="context item type">For every expression, it
                  is possible to establish by static analysis, information about the item type of
                  the context item for evaluation of that expression. This is called the
                     <term>context item type</term> of the expression.</termdef></p><p>The <termref def="dt-context-item-type"/> of an expression
               is a <termref def="dt-utype"/>.</p><p>The semantics of every <termref def="dt-construct">construct</termref>, defined in
               this specification or in the XPath specification, describe how the <xtermref spec="XT40" ref="dt-focus"/> for evaluating each <termref def="dt-operand"/> of the construct
               is determined. In most cases the focus is the same as that of the parent construct.
               In some cases the focus is determined by evaluating some other expression, for
               example in the expressions <code nobreak="false">A/B</code>, <code nobreak="false">A!B</code>, <code nobreak="false">A[B]</code>, 
               <code nobreak="false">A?[B]</code>, or <code nobreak="false">A -&gt; B</code>
               the focus for evaluating <var>B</var> is <var>A</var>. More generally:</p><ulist><item><p><termdef id="dt-focus-changing-construct" term="focus-changing construct">A
                           <term>focus-changing construct</term> is a <termref def="dt-construct"/>
                        that has one or more <termref def="dt-operand">operands</termref> that are
                        evaluated with a different <xtermref spec="XT40" ref="dt-focus"/> from the parent
                        construct.</termdef></p><note><p>Examples of focus-changing constructs include the instructions
                           <elcode>xsl:for-each</elcode>, <elcode>xsl:iterate</elcode>, and
                           <elcode>xsl:for-each-group</elcode>; path expressions, filter
                        expressions, and simple mapping expressions; and all patterns.</p></note></item><item><p><termdef id="dt-controlling-operand" term="controlling operand">Within a
                           <termref def="dt-focus-changing-construct"/> there is in many cases one
                           <termref def="dt-operand">operand</termref> whose value determines the
                           <xtermref spec="XT40" ref="dt-focus"/> for evaluating other operands; this is referred
                        to as the <term>controlling operand</term>.</termdef></p><note><p>For example, the controlling operand of an <elcode>xsl:for-each</elcode>,
                           <elcode>xsl:iterate</elcode>, or <elcode>xsl:for-each-group</elcode>
                        instruction is the expression in its <code nobreak="false">select</code> attribute; the
                        controlling operand of a filter expression <code nobreak="false">E[P]</code> is
                           <code nobreak="false">E</code>, and the controlling operand of a simple mapping
                        expression <code nobreak="false">A!B</code> is <code nobreak="false">A</code>.</p></note></item><item><p><termdef id="dt-controlled-operand" term="controlled operand">Within a <termref def="dt-focus-changing-construct"/> there are one or more <termref def="dt-operand">operands</termref> 
                    that are evaluated with a <xtermref spec="XT40" ref="dt-focus"/> determined by the <termref def="dt-controlling-operand"/>
                        (or in some cases such as
                              <elcode>xsl:on-completion</elcode>, with an <xtermref spec="XT40" ref="dt-absent"/>
                           <xtermref spec="XT40" ref="dt-focus"/>); these are referred to as
                           <term>controlled operands</term>.</termdef></p><note><p>For example, the main controlled operand of an
                        <elcode>xsl:for-each</elcode>, <elcode>xsl:iterate</elcode>, or
                           <elcode>xsl:for-each-group</elcode> instruction is the contained sequence
                        constructor; the controlled operand of a filter expression <code nobreak="false">E[P]</code>
                        is <code nobreak="false">P</code>, and the controlled operand of a simple mapping expression
                           <code nobreak="false">A!B</code> is <code nobreak="false">B</code>.</p></note></item><item><p><termdef id="dt-focus-setting-container" term="focus-setting container">The
                           <term>focus-setting container</term> of a construct <var>C</var> is the
                        innermost <termref def="dt-focus-changing-construct"/>
                        <var>F</var> (if one exists) such that <var>C</var> is directly or
                        indirectly contained in a <termref def="dt-controlled-operand"/> of
                           <var>F</var>. If there is no such construct
                              <var>F</var>, then the focus-setting container is the containing
                              <xtermref spec="XT40" ref="dt-declaration"/>, for example an
                              <elcode>xsl:function</elcode> or <elcode>xsl:template</elcode>
                           element.</termdef></p><note><p>For example, if an instruction appears as a child of
                           <elcode>xsl:for-each</elcode>, then its focus-setting container is the
                           <elcode>xsl:for-each</elcode> instruction; if an expression appears
                        within the predicate of a filter expression, its focus-setting container is
                        the filter expression.</p></note></item></ulist><p>The <termref def="dt-context-item-type"/> of a construct <var>C</var> is the first of
               the following that applies:</p><olist><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is an
                        <elcode>xsl:function</elcode> element, an inline function declaration, or an
                        <elcode>xsl:on-completion</elcode> element, then the context item type is
                        <code nobreak="false">U{}</code>.</p><note><p>This is essentially an error case; expressions that depend on the focus
                        should not normally appear within a construct that sets the focus to
                           <xtermref spec="XT40" ref="dt-absent"/>.</p></note></item><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is an
                        <elcode>xsl:source-document</elcode> instruction, then the context item type is <code nobreak="false">U{document-node()}</code>.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is a
                        <xtermref spec="XT40" ref="dt-template-rule"/>, then the context item type is the
                        <termref def="dt-match-type"/> of the match pattern of the template rule,
                     defined below.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is a
                        <code nobreak="false">PredicatePattern</code>, then the context item type is <code nobreak="false">U{*}</code>.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> is a <xtermref spec="XT40" ref="dt-global-variable"/>
                     declaration, the context item type is determined by the <code nobreak="false">type</code> attribute
                     of the <elcode>xsl:global-context-item</elcode> declaration, defaulting to <code nobreak="false">U{*}</code>,
                     or <code nobreak="false">U{}</code> if the <elcode>xsl:global-context-item</elcode> declaration specifies
                     <code nobreak="false">use="absent"</code>.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> is any other <xtermref spec="XT40" ref="dt-declaration"/>, for example <elcode>xsl:key</elcode> or 
                     <elcode>xsl:accumulator</elcode>, the
                     context item type is <code nobreak="false">U{*}</code>.</p></item><item><p>Otherwise, the context item type is the <termref def="dt-static-type"/> (see
                        <specref ref="determining-static-type"/>) of the <termref def="dt-controlling-operand"/> of the <termref def="dt-focus-setting-container"/> of <var>C</var>.</p></item></olist><p><termdef id="dt-match-type" term="match type">The
                     <term>match type</term> of a <xtermref spec="XT40" ref="dt-pattern"/> is the most specific
                     <termref def="dt-utype"/> that is known to match all items that the pattern can
                  match.</termdef> The match type of a pattern is the inferred <termref def="dt-static-type"/> of the pattern’s equivalent expression, determined
               according to the rules in <specref ref="determining-static-type"/>. For example, the
               match type of the pattern <code nobreak="false">para[1]</code> is <code nobreak="false">U{element()}</code>, while
               that of the pattern <code nobreak="false">@code[.='x']</code> is <code nobreak="false">U{attribute()}</code></p></div2><div2 id="operand-roles-and-usage"><head>The Effect of Operand Usage</head><p>The effect of <termref def="dt-operand-usage"/> on streamability analysis 
             is illustrated in the following examples:</p><example><head>The Effect of Operand Usage on the Streamability of a Context Item
                     Expression</head><p>Consider the following construct:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:source-document streamable="yes" href="emps.xml"&gt;
  &lt;xsl:for-each select="*/emp"&gt;
    &lt;xsl:value-of select="."/&gt;
  &lt;/xsl:for-each&gt;
&lt;/xsl:source-document&gt;</eg><p>To assess the streamability, we follow the following logic:</p><olist><item><p>The top-level construct is a <xtermref spec="XT40" ref="dt-sequence-constructor"/>. It
                           is evaluated with a document node as the context item, and with a
                              <termref def="dt-striding"/> posture.</p></item><item><p>The sequence constructor has one child <xtermref spec="XT40" ref="dt-instruction"/>,
                           which has an <termref def="dt-operand-usage"/> of <termref def="dt-transmission"/>.</p></item><item><p>The <elcode>xsl:for-each</elcode> instruction evaluates its
                              <code nobreak="false">select</code> expression, with the context item and <termref def="dt-posture"/> unchanged.</p></item><item><p>The step <code nobreak="false">child::*</code> is evaluated with this context item and
                           posture. The posture transition rules permit this; we now have a sequence
                           of child elements, and still a <termref def="dt-striding"/> posture.</p></item><item><p>The same applies to the next step, <code nobreak="false">child::emp</code></p></item><item><p>The content of the <elcode>xsl:for-each</elcode> instruction is a
                              <xtermref spec="XT40" ref="dt-sequence-constructor"/> which itself has a single
                              <termref def="dt-operand"/>, the <elcode>xsl:value-of</elcode>
                           instruction.</p></item><item><p>The <elcode>xsl:value-of</elcode> instruction is evaluated once for each
                              <code nobreak="false">emp</code> child, with that child as context item and in a
                              <termref def="dt-striding"/> posture. This instruction uses the
                              <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-usage"/> of the <code nobreak="false">select</code> expression is
                              <termref def="dt-absorption"/>. This means that the result of the
                              <elcode>xsl:value-of</elcode> instruction is <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></item><item><p>The result of the trivial sequence constructor contained in the
                              <elcode>xsl:for-each</elcode> instruction is therefore <termref def="dt-grounded"/> and <termref def="dt-consuming"/></p></item><item><p>The result of the <elcode>xsl:for-each</elcode> instruction (see <specref ref="streamability-xsl-for-each"/>) is therefore <termref def="dt-grounded"/> and <termref def="dt-consuming"/></p></item><item><p>The result of the trivial sequence constructor contained in the
                              <elcode>xsl:source-document</elcode> instruction is therefore <termref def="dt-grounded"/> and <termref def="dt-consuming"/></p></item><item><p>The <elcode>xsl:source-document</elcode> instruction is therefore <termref def="dt-guaranteed-streamable"/>.</p></item></olist><p>Now consider a slightly different construct:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:source-document streamable="yes" href="emps.xml"&gt;
  &lt;xsl:for-each select="*/emp"&gt;
    &lt;xsl:sequence select="."/&gt;
  &lt;/xsl:for-each&gt;
&lt;/xsl:source-document&gt;</eg><p>To assess the streamability, we follow the following logic:</p><olist><item><p>The top-level construct is a <xtermref spec="XT40" ref="dt-sequence-constructor"/>. It
                           is evaluated with a document node as the context item, and with a
                              <termref def="dt-striding"/> posture.</p></item><item><p>The sequence constructor has one child <xtermref spec="XT40" ref="dt-instruction"/>,
                           which has an <termref def="dt-operand-usage"/> of <termref def="dt-transmission"/>.</p></item><item><p>The <elcode>xsl:for-each</elcode> instruction evaluates its
                              <code nobreak="false">select</code> expression, with the context item and <termref def="dt-posture"/> unchanged.</p></item><item><p>The step <code nobreak="false">child::*</code> is evaluated with this context item and
                           posture. The posture transition rules permit this; we now have a sequence
                           of child elements, and still a <termref def="dt-striding"/> posture.</p></item><item><p>The same applies to the next step, <code nobreak="false">child::emp</code></p></item><item><p>The content of the <elcode>xsl:for-each</elcode> instruction is a
                              <xtermref spec="XT40" ref="dt-sequence-constructor"/> which itself has a single
                           operand, the <elcode>xsl:sequence</elcode> instruction.</p></item><item><p>The <elcode>xsl:sequence</elcode> instruction is evaluated once for each
                              <code nobreak="false">emp</code> child, with that child as context item and in a
                              <termref def="dt-striding"/> posture. This instruction uses the
                              <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-usage"/> of the <code nobreak="false">select</code> expression is
                              <termref def="dt-transmission"/>. This means that the result of the
                              <elcode>xsl:sequence</elcode> instruction is <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p></item><item><p>The result of the trivial sequence constructor contained in the
                              <elcode>xsl:for-each</elcode> instruction is therefore also <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p></item><item><p>The result of the <elcode>xsl:for-each</elcode> instruction (see <specref ref="streamability-xsl-for-each"/>) is therefore <termref def="dt-striding"/> and <termref def="dt-consuming"/> (the wider of the sweeps of the
                                 <code nobreak="false">select</code> expression and the sequence
                              constructor).</p></item><item><p>The result of the trivial sequence constructor contained in the
                              <elcode>xsl:source-document</elcode> instruction is therefore <termref def="dt-striding"/> and <termref def="dt-consuming"/>.</p></item><item><p>Since the result is not <termref def="dt-grounded"/>,  the <elcode>xsl:source-document</elcode>
                           instruction is therefore not <termref def="dt-guaranteed-streamable"/>.</p></item></olist><p>Expressed informally, the result of a <termref def="dt-declared-streamable"/> 
                     <elcode>xsl:source-document</elcode> instruction
                     (or of a <termref def="dt-declared-streamable"/> template rule) 
                     must not contain streamed nodes. The reason
                     for this is that once streamed nodes are returned to constructs that are not
                     declared streamable and therefore have no streamability constraints, there is
                     no way to analyze what happens to them, and thus to guarantee
                     streamability.</p></example><example><head>The Effect of Operand Roles on the Streamability of Path Expressions</head><p>Consider the expression <code nobreak="false">.//chapter</code>.</p><p>When this appears as an argument to the function <xfunction>count</xfunction>
                     or <xfunction>exists</xfunction>, it can be streamed (it is a <termref def="dt-consuming"/> expression, meaning that the subtree rooted at the
                     context item needs to be read in order to evaluate the expression). A possible
                     strategy for performing a streamed evaluation is to read all descendants of the
                     context item in document order, checking each one to see whether its name is
                        <code nobreak="false">chapter</code>. The <termref def="dt-sweep"/> of the expression will
                     be <termref def="dt-consuming"/>, and its <termref def="dt-posture"/> will be
                        <termref def="dt-crawling"/>.</p><p>The <termref def="dt-operand-usage"/> (the usage of the argument to
                        <xfunction>count</xfunction> or <xfunction>exists</xfunction>) is defined as
                        <termref def="dt-inspection"/>. The <termref def="dt-general-streamability-rules"/> show that when the posture of an
                        <termref def="dt-operand"/> is <termref def="dt-crawling"/> and the <termref def="dt-operand-usage"/> is <termref def="dt-inspection"/>, the resulting
                     expression is <termref def="dt-grounded"/>
                        and <termref def="dt-consuming"/>. This means that (in the absence of other
                        consuming expressions) the containing template or function will generally be
                        streamable.</p><p>In the expression <code nobreak="false">tail(.//chapter)</code>, the
                        <termref def="dt-operand-usage"/> is classified as <termref def="dt-transmission"/>, meaning that the nodes are simply passed up the
                     tree to the next containing expression. In general, when a <termref def="dt-crawling"/> expression is passed as an argument and the operand role
                     is <termref def="dt-transmission"/>, the containing expression will also be
                        <termref def="dt-crawling"/>. However, there is an exception where the
                     expression is known to deliver a singleton (for example,
                        <code nobreak="false">head(.//chapter)</code>). In this case the returned sequence cannot
                     contain any nested nodes, so it is <termref def="dt-crawling"/>.</p><p>When the same expression appears as an argument to an atomizing function
                        <xfunction>string-join</xfunction>, the processor knows that it will need to
                     access the subtree of each selected <code nobreak="false">section</code> element in order to
                     compute the result of the function (the argument to
                        <xfunction>string-join</xfunction> is classified as having <termref def="dt-operand-usage"/>
                     <termref def="dt-absorption"/>). The processor does not know whether these
                     subtrees will be nested (one
                        <code nobreak="false">section</code> might contain another). In most cases they will not be nested, because atomizing a
                        sequence that contains nested nodes is not generally a useful thing to do.
                        The streamability analysis therefore makes an optimistic assumption, by
                        treating atomization of a <termref def="dt-crawling"/> expression as a
                        streamable operation. In the worst case, where it turns out that the
                        selected nodes are indeed nested, the processor must handle this, typically
                        by buffering the content of inner nodes until the end tag of the outer nodes
                        is reached.</p><p>This treatment of nodes in a <termref def="dt-crawling"/> expression applies to all cases in which the content of
                     the nodes is handled in a way defined entirely by the rules of this
                     specification: for example, operations such as atomization, obtaining the
                     string value of nodes, deep copy of nodes, and the
                        <xfunction>deep-equal</xfunction> function. It does not extend to cases
                     where the processing applied to the nodes is user-defined: for example,
                     operations such as <elcode>xsl:apply-templates</elcode>,
                        <elcode>xsl:for-each</elcode>, or <elcode>xsl:for-each-group</elcode>. In
                     these cases, the nodes selected for processing must not be nested (a <termref def="dt-crawling"/> <termref def="dt-posture"/> is not permitted in these contexts).</p><p>When a <termref def="dt-crawling"/> expression
                     appears as an argument to a call on a user-defined function, the effect depends on the <termref def="dt-streamability-category"/> of the function, as described in
                           <specref ref="streamable-stylesheet-functions"/>.</p></example></div2><div2 id="posture"><head>Posture</head><p>The <term>posture</term> of a construct indicates the relationship of the nodes
               selected by the <termref def="dt-construct"/> to a <termref def="dt-streamed-document">streamed input document</termref>. The value is one of
               the following:</p><ulist><item><p><termdef id="dt-grounded" term="grounded"><term>Grounded</term>: indicates that
                        the value returned by the construct does not contain nodes from the streamed
                        input document</termdef>. Atomic items and function items are always
                     grounded; nodes are grounded if it is known that they are in a non-streamed
                     document. For example the expressions <code nobreak="false">doc('x')</code> and
                        <code nobreak="false">copy-of(.)</code> both return grounded nodes.</p></item><item><p><termdef id="dt-climbing" term="climbing"><term>Climbing</term>: indicates that
                        streamed nodes returned by the construct are reached by navigating the parent,
                        ancestor[-or-self], attribute, and/or namespace axes from the node at the
                        current streaming position.</termdef> When the <termref def="dt-context-posture"/> is climbing, use of certain
                     axes such as <code nobreak="false">parent</code> and <code nobreak="false">ancestor</code> is permitted, but
                     use of other axes such as <code nobreak="false">child</code> or <code nobreak="false">descendant</code>
                     violates the streamability rules.</p></item><item><p><termdef id="dt-crawling" term="crawling"><term>Crawling</term>: typically
                        indicates that streamed nodes returned by a construct are reached by navigating the
                        descendant[-or-self] axis.</termdef> Nodes reached in this way are potentially nested (one might be an ancestor
                        of another), so further downward navigation is not permitted.
                        Expressions that can be statically determined to
                        return a singleton node (for example <code nobreak="false">head(.//title)</code>) generate a
                        result with no such nesting, so
                        they are striding rather than crawling.</p></item><item><p><termdef id="dt-striding" term="striding"><term>Striding</term>: indicates that
                        the result of a construct contains a sequence of streamed nodes, in document order, that
                        are peers in the sense that none of them is an ancestor or descendant of any
                        other.</termdef> This is typically achieved by using one or more steps
                     involving the child or attribute
                     axes only. Use of the <xfunction>outermost</xfunction> function can also result
                     in a striding posture, as can functions such as
                           <xfunction>head</xfunction> or <xfunction>zero-or-one</xfunction> that
                        ensure the result will be a singleton node.</p></item><item><p><termdef id="dt-roaming" term="roaming"><term>Roaming</term>: indicates that
                        the nodes returned by an expression could be anywhere in the tree, which
                        inevitably means that the construct cannot be evaluated using
                        streaming.</termdef> For example, the <termref def="dt-posture"/> of an axis
                     step using the <code nobreak="false">following</code> or <code nobreak="false">preceding</code> axis will
                     typically be <termref def="dt-roaming"/>, which leads the analysis to conclude
                     that the construct is not streamable.</p></item></ulist><note><p>One way to think about the posture values is as labels for states in a finite
                  state automaton, where the alphabet of symbols accepted by the automaton is the
                  set of 13 XPath axes, and the sentence being parsed is a path expression
                  containing a sequence of axis steps. For example, use of the
                     <code nobreak="false">descendant</code> axis when the current state is <term>striding</term>
                  moves the new state to <term>crawling</term>, and use of the <code nobreak="false">parent</code>
                  axis then takes it to <term>climbing</term>. </p></note><p>The <termref def="dt-posture"/> of a construct is determined in one of several
               ways:</p><ulist><item><p>For axis steps, the posture of the expression is determined by the <termref def="dt-context-posture"/> and the
                     choice of axis. For example, an axis step using the ancestor axis always has a
                     posture of <termref def="dt-climbing"/>, while an axis step using the child
                     axis, if the <termref def="dt-context-posture"/> is <termref def="dt-striding"/>, will itself have a posture of
                        <termref def="dt-striding"/>. The rules for the posture transitions produced
                     by axis steps are given in <specref ref="streamability-of-axis-steps"/>.</p></item><item><p>For many other constructs, the posture is determined by the <termref def="dt-general-streamability-rules"/>. These determine the result posture
                     in terms of the <termref def="dt-operand">operands</termref> of the construct
                     and the way in which each operand is used. For example, a construct that
                     accepts a streamed node as the value of an operand, and atomizes that node,
                     will generally have a posture of <termref def="dt-grounded"/>.</p></item><item><p>Other constructs have their own special rules, which are listed in 
                     <specref ref="streamability-of-constructs"/>. For example, a call 
                    on the <xfunction>root</xfunction> function
                     behaves analogously to an axis step, and is described in 
                    <specref ref="streamability-fn-root"/>. Special rules are needed for:</p><ulist><item><p>Constructs that evaluate an <termref def="dt-operand"/> more than once,
                           such as an XPath <code nobreak="false">for</code> expression;</p></item><item><p>Constructs that have alternatives among their operands, such as an XPath
                              <code nobreak="false">if</code> expression;</p></item><item><p>Constructs that navigate relative to the context item, such as axis
                           steps;</p></item><item><p>Constructs with implicit inputs, such as the context item expression
                              <code nobreak="false">.</code> (dot);</p></item><item><p>Constructs that change the focus, such as a filter expression;</p></item><item><p>Constructs that invoke functions or templates.</p></item></ulist></item></ulist><p>The characterization of an expression as striding, crawling, climbing, or
               roaming applies only to the streamed nodes in the result of the expression. The result of the expression
               may also contain non-streamed (grounded) nodes or atomic items. For example
               if <code nobreak="false">/x/y</code> is a striding expression, then <code nobreak="false">(/x/y | $doc//x)</code> is also striding, given
               that <code nobreak="false">$doc</code> contains non-streamed nodes. The assertion that the nodes in the result of a striding
               expression are in document order and are peers thus applies only to the subset of the nodes that are streamed.</p><note><p>A consequence of this is that when striding expressions are used in a context that requires sorting into
                  document order, for example <code nobreak="false">(/x/y | $doc//x) / @price</code>, the fact that the expression is striding
               does not eliminate the need for the sequence to be re-ordered. However, there will never be a need for the relative
               order of the streamed nodes in the value to change.</p><p>Since the data model leaves the relative order of nodes in different trees implementation-defined, and since streamed
                  and unstreamed nodes will necessarily be in different trees, a useful
               implementation strategy might be to arrange that streamed nodes always precede unstreamed nodes in document order (or vice
               versa). An operation that needs to process the result of a striding expression in document order can then first deliver
               all the streamed nodes (by consuming the input stream) in the order they arrive, and then deliver the unstreamed nodes, 
               suitably sorted.</p></note><div3 id="id-choice-operand-groups"><head>Choice Operand Groups</head><p><termdef id="dt-choice-operand-group" term="choice operand group">For some construct
               kinds, one or more operand roles may be defined to form a <term>choice operand
                  group</term>. This concept is used where it is known that <termref def="dt-operand">operands</termref> are mutually exclusive (for example the
                  <code nobreak="false">then</code> and <code nobreak="false">else</code> clauses in a conditional
               expression).</termdef></p><p><termdef id="dt-combined-posture" term="combined posture" open="true">The
                  <term>combined posture</term> of a <termref def="dt-choice-operand-group"/> is
               determined by the <termref def="dt-posture">postures</termref> of the <termref def="dt-operand">operands</termref> in the group (the <term>operand postures</term>), and is the first of
               the following that applies:</termdef></p><olist><item><p>If any of the operand postures is
                     <termref def="dt-roaming"/>, then the combined posture is <termref def="dt-roaming"/>.</p></item><item><p>If all of the operand postures are
                     <termref def="dt-grounded"/>, then the combined posture is <termref def="dt-grounded"/>.</p></item><item><p>If one or more of the operand postures
                  is <termref def="dt-climbing"/> and the remainder (if any) are <termref def="dt-grounded"/>, then the combined posture is <termref def="dt-climbing"/>.</p></item><item><p>If one or more of the operand postures
                  is <termref def="dt-striding"/> and the remainder (if any) are <termref def="dt-grounded"/>, then the combined posture is <termref def="dt-striding"/>.</p></item><item><p>If one or more of the operand postures
                  is <termref def="dt-crawling"/> and each of the
                     remainder (if any) is either <termref def="dt-striding"/> or <termref def="dt-grounded"/>, then the combined posture is <termref def="dt-crawling"/>.</p></item><item><p>Otherwise (for example, if the group includes both an operand with <termref def="dt-climbing"/> posture and one with <termref def="dt-crawling"/> posture),
                  the combined posture is <termref def="dt-roaming"/>. </p></item></olist><p role="closetermdef"/></div3><div3 id="determining-context-posture"><head>Determining the Context Posture</head><p>In the same way as the type of the context item can be determined for any construct C
               by reference to the type of the construct that establishes the context for the
               evaluation of C, so the posture of the context item C can be determined by reference
               to the posture of the construct that establishes the context.</p><p>The <termref def="dt-context-posture"/> of a construct <var>C</var> is the first of
               the following that applies:</p><olist><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is an
                        <elcode>xsl:function</elcode> declaration, an inline function declaration,
                     or an <elcode>xsl:on-completion</elcode> element, then the context posture is
                        <termref def="dt-roaming"/>.</p><note><p>This is essentially an error case; expressions that depend on the context
                        item should not normally appear within these constructs.</p></note></item><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is an
                        <elcode>xsl:source-document</elcode> instruction, then the context posture is
                     <termref def="dt-striding"/> if the
                     instruction is <termref def="dt-declared-streamable"/>, or <termref def="dt-grounded"/> otherwise.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is a
                        <xtermref spec="XT40" ref="dt-template-rule"/> whose mode is declared with
                        <code nobreak="false">streamable="yes"</code>, then the context posture is <termref def="dt-striding"/>.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is a
                        <xtermref spec="XT40" ref="dt-pattern"/>, then the context posture is <termref def="dt-striding"/>.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> of <var>C</var> is an
                        <elcode>xsl:attribute-set</elcode> declaration with the attribute
                        <code nobreak="false">streamable="yes"</code>, then the context posture is <termref def="dt-striding"/>.</p></item><item><p>If the <termref def="dt-focus-setting-container"/> is any other <xtermref spec="XT40" ref="dt-declaration"/>, for example a global variable declaration, a
                        <xtermref spec="XT40" ref="dt-named-template"/>, or a template rule or attribute set that
                     does not specify <code nobreak="false">streamable="yes"</code>, then the context posture is
                        <termref def="dt-roaming"/>.</p></item><item><p>Otherwise, the context posture is the <termref def="dt-posture"/> of the
                        <termref def="dt-controlling-operand"/> of the <termref def="dt-focus-setting-container"/> of <var>C</var>.</p></item></olist></div3></div2><div2 id="sweep"><head>Sweep</head><p><termdef id="dt-sweep" term="sweep">Every construct has a <term>sweep</term>, which
                  is a measure of the extent to which the current position in the input stream moves
                  during the evaluation of the expression. The sweep is one of: <termref def="dt-motionless"/>, <termref def="dt-consuming"/>, or <termref def="dt-free-ranging"/>
                  .</termdef> This list of
               values is ordered: a <termref def="dt-free-ranging"/> expression has <term>wider
                  sweep</term> than a <termref def="dt-consuming"/> expression, which has
                  <term>wider sweep</term> than a <termref def="dt-motionless"/> expression. </p><p><termdef id="dt-motionless" term="motionless">A <term>motionless</term> <termref def="dt-construct"/> is
                  any construct deemed motionless by the rules for that construct
                     (typically given in <specref ref="streamability-of-constructs"/>).</termdef> 
              Informally, a motionless construct
               is one that can be evaluated without changing the current position in the input
               stream.</p><note><p>The context item expression <code nobreak="false">.</code> is classified as motionless; however a
                  construct that uses <code nobreak="false">.</code> as an <termref def="dt-operand"/> (for example,
                     <code nobreak="false">string(.)</code>) might be <termref def="dt-consuming"/>. The
                  streamability rules effectively consider expressions such as <code nobreak="false">.</code> within
                  the context of the containing construct.</p></note><p><termdef id="dt-consuming" term="consuming">A <term>consuming</term> construct is any
                     <termref def="dt-construct"/> deemed consuming by the rules for that construct
                     (typically given in <specref ref="streamability-of-constructs"/>).</termdef> 
              Informally, a consuming construct
               is one whose evaluation requires repositioning of the input stream from the start of
               the current node to the end of the current node.</p><p><termdef id="dt-free-ranging" term="free-ranging">A <term>free-ranging</term>
                  construct is any <termref def="dt-construct"/> deemed free-ranging by the rules for
                  that construct (typically given in <specref ref="streamability-of-constructs"/>).</termdef> 
               Informally, a
               free-ranging construct is one whose evaluation may require access to information that
               is not available from the subtree rooted at the current node, together with
               information about ancestors of the current node and their attributes.</p><p>The table below shows some examples of expressions having
               different combinations of <termref def="dt-posture"/> and <termref def="dt-sweep"/>.</p><table class="data"><caption>Combinations of Sweep and Posture</caption><thead><tr><th rowspan="1" colspan="1"/><th rowspan="1" colspan="1">Motionless</th><th rowspan="1" colspan="1">Consuming</th><th rowspan="1" colspan="1">Free-Ranging</th></tr></thead><tbody><tr><th rowspan="1" colspan="1">Grounded</th><td rowspan="1" colspan="1"><code nobreak="false">name()</code></td><td rowspan="1" colspan="1"><code nobreak="false">string(title)</code></td><td rowspan="1" colspan="1">See Note</td></tr><tr><th rowspan="1" colspan="1">Climbing</th><td rowspan="1" colspan="1"><code nobreak="false">parent::*</code></td><td rowspan="1" colspan="1"><code nobreak="false">child::x/ancestor::y</code></td><td rowspan="1" colspan="1">See Note</td></tr><tr><th rowspan="1" colspan="1">Striding</th><td rowspan="1" colspan="1"><code nobreak="false">@status</code></td><td rowspan="1" colspan="1"><code nobreak="false">child::*</code></td><td rowspan="1" colspan="1">See Note</td></tr><tr><th rowspan="1" colspan="1">Crawling</th><td rowspan="1" colspan="1">The subexpression <code nobreak="false">.</code> in <code nobreak="false">//a/.</code></td><td rowspan="1" colspan="1"><code nobreak="false">descendant::*</code></td><td rowspan="1" colspan="1"><code nobreak="false">//x[child::y]</code></td></tr><tr><th rowspan="1" colspan="1">Roaming</th><td rowspan="1" colspan="1">See Note</td><td rowspan="1" colspan="1">See Note</td><td rowspan="1" colspan="1"><code nobreak="false">preceding::*</code></td></tr></tbody></table><note><p>In all cases where either the <termref def="dt-posture"/> is <termref def="dt-roaming"/>, or the <termref def="dt-sweep"/> is <termref def="dt-free-ranging"/>, or both, the effect is to make an expression
                  non-streamable. For convenience, therefore, evaluation of the streamability rules
                  in most cases returns the values <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/> only in combination with each other. In cases where the
                  rules return a <termref def="dt-posture"/> of <termref def="dt-roaming"/> combined
                  with some other <termref def="dt-sweep"/>, or a <termref def="dt-sweep"/> of
                     <termref def="dt-free-ranging"/> with some other <termref def="dt-posture"/>,
                  the final result of the analysis is always the same as if the expression were both
                     <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p><p>For an example of a case where an expression is <termref def="dt-roaming"/> but
                  not <termref def="dt-free-ranging"/>, consider the right-hand operand of the
                  relative path expression <code nobreak="false">(preceding::x/.)</code>. The rules for the
                  streamability of a context item expression (see <specref ref="streamability-of-context-item-expression"/>) give <code nobreak="false">.</code> in this
                  context a <termref def="dt-roaming"/> posture, combined with <termref def="dt-motionless"/> sweep. But the relative path expression as a whole is
                     <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/> (see <specref ref="streamability-of-path-expressions"/>), so the apparent inconsistency is
                  transient.</p></note></div2><div2 id="general-streamability-rules"><head>General Streamability Rules</head><p><termdef id="dt-general-streamability-rules" term="general streamability rules">Many <termref def="dt-construct">constructs</termref> share the same
                     streamability rules. These rules, referred to as the <term>general
                        streamability rules</term>, are defined here.</termdef></p><p>Examples of constructs that use these rules are: an arithmetic expression, an
                     <xtermref spec="XT40" ref="dt-attribute-value-template"/>, 
                 a <xtermref spec="XT40" ref="dt-sequence-constructor"/>, 
                  the <elcode>xsl:text</elcode> and <elcode>xsl:value-of</elcode> instructions,
                  and a call to the <xfunction>doc</xfunction> function.</p><p>The rules determine both the <termref def="dt-posture"/> and <termref def="dt-sweep">sweep</termref> of a construct. To determine the posture and
                  sweep of a construct <var>C</var>, assuming these general rules are applicable to
                  that kind of construct:</p><olist><item><p>For each <termref def="dt-operand"/> of <var>C</var>:</p><olist><item><p>Establish:</p><olist><item><p>The <termref def="dt-static-type"/>
                                    <var>T</var> of the operand (see <specref ref="determining-static-type"/>). </p><note><p>The static type is a <termref def="dt-utype"/>. For example,
                                       the static type of the expression <code nobreak="false">(@*, *)</code> is
                                          <var>U{element(), attribute()}</var>.</p></note></item><item><p>The <termref def="dt-sweep"/>
                                    <var>S</var> and <termref def="dt-posture"/>
                                    <var>P</var> of the operand (by applying the rules appropriate to that operand).</p></item><item><p>The <termref def="dt-operand-usage"/>
                                    <var>U</var> corresponding to the <termref def="dt-operand-role">role</termref> 
                                   of the operand within <var>C</var>.</p></item></olist></item><item><p>Compute the adjusted sweep <var>S'</var> of the <termref def="dt-operand"/> by taking the first of the following that
                              applies:</p><olist><item><p>If <var>S</var> is <termref def="dt-free-ranging"/> or
                                       <var>P</var> is <termref def="dt-roaming"/>, then
                                       <var>S'</var> is <termref def="dt-free-ranging"/>. (In this
                                    case the posture and sweep of <var>C</var> are <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>,
                                    regardless of any other operands.)</p></item><item><p>If <var>P</var> is <termref def="dt-grounded"/>, then
                                       <var>S'</var> is <var>S</var>.</p></item><item><p>Otherwise (<var>P</var> is not <termref def="dt-grounded"/>,
                                    which implies that the <termref def="dt-operand"/> is capable of returning streamed
                                    nodes), compute <var>S'</var> as follows:</p><olist><item><p>Compute the adjusted usage <var>U'</var> as follows:</p><olist><item><p>If <var>U</var> is <termref def="dt-absorption"/>
                                                  and the
                                                  intersection of <var>T</var> with
                                                  <var>U{element(), document-node()}</var> is
                                                  <var>U{}</var> (that is, if <var>T</var> is a type
                                                  that does not allow nodes with children),
                                                  then <var>U'</var> is <termref def="dt-inspection"/>.</p><note><p>This is because the entire subtree of nodes
                                                  such as text nodes is available without reading
                                                  further data from the input stream.</p></note></item><item><p>Otherwise, <var>U'</var> is <var>U</var>.</p></item></olist></item><item><p>Compute the adjusted <termref def="dt-sweep"/>
                                          <var>S'</var> from the table below:</p><table class="data"><caption>Computing the Adjusted Sweep of an Expression</caption><thead><tr><th rowspan="2" colspan="1">Posture (P)</th><th colspan="4" rowspan="1">Adjusted Usage (U')</th></tr><tr><th rowspan="1" colspan="1">Absorption</th><th rowspan="1" colspan="1">Inspection</th><th rowspan="1" colspan="1">Transmission</th><th rowspan="1" colspan="1">Navigation</th></tr></thead><tbody><tr><th rowspan="1" colspan="1">Climbing</th><td rowspan="1" colspan="1">Free-ranging</td><td rowspan="1" colspan="1"><var>S</var></td><td rowspan="1" colspan="1"><var>S</var></td><td rowspan="1" colspan="1">Free-ranging</td></tr><tr><th rowspan="1" colspan="1">Striding</th><td rowspan="1" colspan="1">Consuming</td><td rowspan="1" colspan="1"><var>S</var></td><td rowspan="1" colspan="1"><var>S</var></td><td rowspan="1" colspan="1">Free-ranging</td></tr><tr><th rowspan="1" colspan="1">Crawling</th><td rowspan="1" colspan="1">Consuming</td><td rowspan="1" colspan="1"><var>S</var></td><td rowspan="1" colspan="1"><var>S</var></td><td rowspan="1" colspan="1">Free-ranging</td></tr></tbody></table></item></olist></item></olist></item><item><p><termdef id="dt-potentially-consuming" term="potentially consuming" open="true">An
                                    <termref def="dt-operand"/> is <term>potentially
                                    consuming</term> if at least one of the following conditions
                                 applies:</termdef></p><olist><item><p>The operand’s adjusted <termref def="dt-sweep"/>
                                    <var>S'</var> is <termref def="dt-consuming"/>.</p></item><item><p>The <termref def="dt-operand-usage"/> is <termref def="dt-transmission"/> and the operand is not <termref def="dt-grounded"/>.</p></item></olist><p role="closetermdef"/></item></olist></item><item><p>Having computed the adjusted sweep <var>S'(o)</var> of each <termref def="dt-operand"/>
                        <var>o</var>, the <termref def="dt-posture"/> and <termref def="dt-sweep">sweep</termref> of <var>C</var> are the first of the following that
                        applies:</p><olist><item><p>If <var>C</var> has no operands, then <termref def="dt-grounded"/> and
                                 <termref def="dt-motionless"/>.</p></item><item><p>If any operand <var>o</var> has an adjusted sweep <var>S'(o)</var> of
                                 <termref def="dt-free-ranging"/>, then <termref def="dt-roaming"/>
                              and <termref def="dt-free-ranging"/>.</p></item><item><p>If more than one operand is <termref def="dt-potentially-consuming"/>, then:</p><olist><item><p>If all these operands form part of a <termref def="dt-choice-operand-group"/>, then the <termref def="dt-posture"/> of <var>C</var> is the <termref def="dt-combined-posture"/> of the operands in this group,
                                    and the <termref def="dt-sweep"/> of <var>C</var> is the widest
                                       <termref def="dt-sweep"/> of the operands in this group</p></item><item><p>If all these operands have <var>S'</var> = <termref def="dt-motionless"/>, (which necessarily means they have
                                       <var>U'</var> = <var>U</var> = <termref def="dt-transmission"/>) and if they all have the same <termref def="dt-posture"/>
                                    <var>P0</var>, then <termref def="dt-motionless"/> with <termref def="dt-posture"/>
                                    <var>P0</var>.</p><note><p>For example, the expression <code nobreak="false">(@a, @b)</code> is
                                       motionless and striding.</p></note></item><item><p>Otherwise, <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item></olist></item><item><p>If exactly one operand <var>o</var>
                              is <termref def="dt-potentially-consuming"/>, then:</p><olist><item><p>If <var>o</var> is a <termref def="dt-higher-order-operand"/> of
                                       <var>C</var>, then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If the <termref def="dt-operand-usage"/> of <var>o</var> is
                                       <termref def="dt-absorption"/> or <termref def="dt-inspection"/>, then <termref def="dt-grounded"/> and
                                       <termref def="dt-consuming"/>.</p></item><item><p>If the <termref def="dt-posture"/> of <var>o</var> is <termref def="dt-crawling"/> and <var>C</var> is a function call of a
                                       built-in function
                                    whose signature indicates a return type with a maximum
                                    cardinality of one then <termref def="dt-striding"/> and the
                                    adjusted <termref def="dt-sweep"/> of <var>o</var>.</p><note><p>Although this rule is written in
                                       general terms, the only functions that it applies to (at the
                                       time of publication) are <xfunction>head</xfunction>,
                                          <xfunction>exactly-one</xfunction>, and
                                          <xfunction>zero-or-one</xfunction>. This rule only
                                       applies if the argument usage is transmission (other cases
                                       having been handled by earlier rules); of the built-in
                                       functions, the three functions listed are the only ones
                                       having an argument with usage transmission and a return type
                                       with maximum cardinality one.</p></note></item><item><p>Otherwise (the <termref def="dt-operand-usage"/> of <var>o</var>
                                    is <termref def="dt-transmission"/>), the <termref def="dt-posture"/> and adjusted <termref def="dt-sweep"/> of
                                       <var>o</var>.</p></item></olist></item><item><p>Otherwise (all operands are <termref def="dt-motionless"/>) <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item></olist></item></olist><note><p>The rules ensure that if more than one <termref def="dt-operand"/> is <termref def="dt-consuming"/>, that is, if more than one operand reads the subtree of
                     the context node in a way that would cause the current position of the input
                     stream to change, then the construct is not streamable.</p><p>The rules also prevent multiple streamed nodes being returned in the result of
                     an expression if they are delivered by
                        different operands. For example, the expression <code nobreak="false">count((..,
                        *))</code> is not guaranteed streamable. This is to make static analysis
                     possible: the posture needs to be statically determined to ensure that
                     streaming does not fail at execution time. It is permitted, however, for
                     streamed nodes to be mixed in a sequence with non-streamed nodes or with atomic
                     items; in this case the posture of the result will be that of the streamed
                     nodes. It is also permitted to have multiple
                        operands delivering streamed nodes in different branches of a conditional,
                        provided the sweep and posture are compatible: for example <code nobreak="false">if (X) then
                           @name else name</code> is guaranteed streamable.</p><p>Expressions that have more than one operand
                  with usage <termref def="dt-transmission"/>, for example <code nobreak="false">(A, B)</code>,
                  or <code nobreak="false">(A | B)</code>, or <code nobreak="false">insert-before(A, n, B)</code>, generally allow only one of these operands to select
                  streamed nodes. The result of the expression will contain
                  a mixture of streamed and grounded nodes, but its posture and sweep will be
                  that of the streamed operand. The nodes in the result will not necessarily be in document order,
                  but the subset of the nodes that are streamed will always be in document order.</p></note><div3 id="general-streamability-examples"><head>Examples of the General Streamability Rules</head><p>This section provides some examples of how the general streamability rules
                  operate. In each example, the emphasis is on the outermost construct shown;
                  explanations for how the sweep and posture of its operands are derived are not
                  given, though in many cases they are explained in earlier examples.</p><p>The examples assume that the context item type for evaluation of the expression
                  shown is an element node, and that its posture is striding.</p><ulist><item><p><code nobreak="false">2 + 2</code> is grounded and motionless, because both the operands are
                        grounded and motionless.</p></item><item><p><code nobreak="false">price * 2</code> is grounded and consuming, because one of the
                        operands is consuming and the relevant operand usage is absorption.</p></item><item><p><code nobreak="false">price - discount</code> is roaming and free-ranging, because both the
                        operands are consuming (and they are not members of a parallel operand
                        group).</p></item><item><p><code nobreak="false">price * @discount</code> is grounded and consuming. The left-hand operand is consuming and
                        the corresponding operand usage is absorption, while the right-hand operand is motionless, again with an
                        operand usage of absorption, and its item type is <code nobreak="false">attribute()</code>
                        which changes the effective usage to inspection.</p></item><item><p><code nobreak="false">a/b/c</code> is striding and consuming. This is determined not by the
                        general streamability rules, but by the rules for path expressions in
                           <specref ref="streamability-of-path-expressions"/>.</p></item><item><p><code nobreak="false">a//c</code> is crawling and consuming. This is similarly determined by
                        the rules for path expressions in <specref ref="streamability-of-path-expressions"/>.</p></item><item><p><code nobreak="false">count(a/b/c)</code> is grounded and consuming, because the operand
                        (the argument to the count function) is striding and consuming (see earlier
                        example) and the operand usage is inspection.</p></item><item><p><code nobreak="false">sum(a/b/c)</code> is grounded and consuming, because the operand (the
                        argument to the <code nobreak="false">sum</code>
                        function) is striding and consuming (see earlier example) and the operand
                        usage is absorption.</p></item><item><p><code nobreak="false">count(descendant::c)</code> is grounded and
                        consuming, because the operand (the argument to the <code nobreak="false">count</code>
                        function) is crawling and consuming (see earlier example) and the operand
                        usage is inspection.</p></item><item><p><code nobreak="false">tail(descendant::c)</code> is crawling and
                        consuming. The operand is crawling, the operand usage is transmission, so
                        the posture and sweep of the result are the same as the posture and sweep of
                        the consuming operand.</p></item><item><p><code nobreak="false">unordered(a|b)</code> is crawling and
                        consuming. The operand (the argument to the <code nobreak="false">unordered</code> function)
                        is crawling (see <specref ref="streamability-of-union-expressions"/>), and
                        the operand usage is transmission, so the posture and sweep of the result
                        are the same as the posture and sweep of the consuming operand.</p></item><item><p><code nobreak="false">zero-or-one(descendant::c)</code> is
                        striding and consuming. Although the operand is crawling, the operand usage
                        is transmission and the cardinality of the expression is zero or one, so the
                        posture of the result is striding. The same analysis applies to
                           <code nobreak="false">exactly-one(descendant::c)</code> and to
                           <code nobreak="false">head(descendant::c)</code>.</p></item><item><p><code nobreak="false">sum(descendant::c)</code> is grounded and
                        consuming, because the operand (the argument to the <code nobreak="false">sum</code>
                        function) is crawling and consuming (see earlier example) and the operand
                        usage is absorption. In theory (although it is unlikely in practice) the
                        selected <code nobreak="false">c</code> elements might be
                           nested one inside another. The processor is expected to handle
                        this situation, which may require some buffering. For example, given the
                        untyped source document
                           <code nobreak="false">&lt;a&gt;&lt;c&gt;&lt;c&gt;1&lt;/c&gt;&lt;c&gt;2&lt;/c&gt;&lt;c&gt;3&lt;/c&gt;&lt;/c&gt;&lt;/a&gt;</code>, the
                        result of the expression is <code nobreak="false">129</code> (123 + 1 + 2 + 3), and to
                        evaluate this, a streaming processor will typically maintain a stack of
                        buffers to accumulate the typed values of each of the four <code nobreak="false">c</code>
                        elements during a single pass of the source document. </p></item><item><p><code nobreak="false">"Q{" || namespace-uri(.) || "}" || local-name(.)</code> is grounded
                        and motionless. The two literal operands are grounded and motionless because
                        they have no operands; the two function calls are grounded and motionless
                        because they have a single operand that is striding and motionless, with an
                        operand usage of inspection.</p></item><item><p><code nobreak="false">copy-of(.)/head/following-sibling::*</code> is grounded and consuming.
                        The left-hand operand
                           <code nobreak="false">copy-of(.)/head</code> is grounded and consuming because, under the
                        rules in <specref ref="streamability-of-path-expressions"/>, its left-hand operand
                           <code nobreak="false">copy-of(.)</code> is grounded and consuming. This in turn is
                        because <code nobreak="false">.</code> is striding and motionless, and the operand usage is
                        absorption.</p></item><item><p><code nobreak="false">if ($discounted) then price else discounted-price</code> is striding
                        and consuming, because the two branches of the conditional are both striding
                        and consuming, and they form a <termref def="dt-choice-operand-group"/> with
                        usage transmission.</p></item><item><p><code nobreak="false">if ($gratis) then 0 else price</code> is striding and consuming
                        because there is only one consuming operand (the fact that it is part of a
                           <termref def="dt-choice-operand-group"/> does not affect the
                        reasoning).</p></item><item><p><code nobreak="false">count((author, editor))</code> is roaming and free-ranging. The first
                        argument to the <code nobreak="false">count</code> function is an expression with two
                        operands, both having usage=transmission, and neither being grounded.</p></item><item><p><code nobreak="false">count((author | editor))</code> is grounded and consuming. A union
                        expression is not subject to the general streamability rules; it has its own
                        rules, defined in <specref ref="streamability-of-union-expressions"/>, which
                        establish in this case that the argument to the <xfunction>count</xfunction>
                        is <termref def="dt-crawling"/> and <termref def="dt-consuming"/>. The
                           <xfunction>count</xfunction> function does follow the general
                        streamability rules, with an operand usage of <termref def="dt-inspection"/>: under rule 1(b)(iii)(B) the adjusted sweep is <termref def="dt-consuming"/>, and rule 2(d)(iii) then applies.</p></item><item><p><code nobreak="false">('{', author, '}')</code> is striding and consuming. Exactly one
                        operand is consuming; it has usage <termref def="dt-transmission"/>, so the
                        result has the posture and sweep of that operand. (The formal analysis
                        treats comma as a binary operator, but the same result can be obtained by
                        treating the content of the parenthesized expression as an expression with
                        three operands.)</p></item></ulist></div3></div2></div1><div1 id="streaming-source-documents"><head>Streaming Source Documents</head><p>The <elcode>xsl:source-document</elcode> instruction reads a source document whose URI is
               supplied, and processes the content of the document  by evaluating the
               contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>. 
               The <code nobreak="false">streamable</code> attribute (default <code nobreak="false">"no"</code>)
            allows streamed processing to be requested.</p><p>For example, if a document represents a book holding a sequence of chapters, then the
               following code can be used to split the book into multiple XML files, one per
               chapter, without allocating memory to hold the entire book in memory at one time:</p><eg xml:space="preserve" role="xslt-instruction">&lt;xsl:source-document streamable="yes" href="book.xml"&gt;
  &lt;xsl:for-each select="book"&gt;             
    &lt;xsl:for-each select="chapter"&gt;
      &lt;xsl:result-document href="chapter{position()}.xml"&gt;
        &lt;xsl:copy-of select="."/&gt;
      &lt;/xsl:result-document&gt;
    &lt;/xsl:for-each&gt;
  &lt;/xsl:for-each&gt;  
&lt;/xsl:source-document&gt;</eg><p>The <xfunction>stream-available</xfunction> function can be used to determine whether a
    particular document is available for streamed processing: see <xspecref spec="XT40" ref="func-stream-available"/>.</p><div2 id="source-document-streamability"><head>Streamability of <elcode>xsl:source-document</elcode></head><p>The <elcode>xsl:source-document</elcode> instruction is 
                   <termref def="dt-guaranteed-streamable"/> if both the following conditions are satisfied:</p><olist><item><p>The instruction is <termref def="dt-declared-streamable"/>, by specifying
               <code nobreak="false">streamable="yes"</code>.</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> is 
                 <termref def="dt-grounded"/>, as assessed using
               the streamability analysis in <specref ref="streamability"/>. The consequences of
               being or not being guaranteed streamable depend on the processor conformance level,
               and are explained in <specref ref="streamability-guarantees"/>.</p></item></olist><note><p>The rules for <termref def="dt-guaranteed-streamable">guaranteed streamability</termref>
                  ensure that the sequence constructor (and therefore the
                     <elcode>xsl:source-document</elcode> instruction) cannot return any nodes from a
                     <termref def="dt-streamed-document">streamed document</termref>. For example,
                  it cannot contain the instruction <code nobreak="false">&lt;xsl:sequence
                     select="//chapter"/&gt;</code>. If nodes from this document are to be returned,
                  they must first be copied, for example by using the
                        <elcode>xsl:copy-of</elcode> instruction or by calling the
                     <function>copy-of</function> or <function>snapshot</function> functions.</p><p>Because the <elcode>xsl:source-document</elcode> instruction cannot (if it satisfies the rules for guaranteed
                     streamability) return nodes from the streamed document, any nodes it
                  does return will be conventional (unstreamed) nodes that can be processed without
                  restriction. For example, if <elcode>xsl:source-document</elcode> is invoked within a
                     <xtermref spec="XT40" ref="dt-stylesheet-function">stylesheet function</xtermref>
                  <code nobreak="false">f:firstChapter</code>, and the sequence constructor consists of the
                  instruction <code nobreak="false">&lt;xsl:copy-of select="//chapter"/&gt;</code>, then the calling
                  code can manipulate the resulting <code nobreak="false">chapter</code> elements as ordinary trees
                  rooted at parentless element nodes.</p><p>If the sequence constructor in an
                     <elcode>xsl:source-document</elcode> instruction were to return nodes from the document
                  for which streaming has been requested, the instruction would not be guaranteed
                  streamable. Processors that support the streaming feature would then not be
                  required to process it in a streaming manner, and this specification imposes no
                  restrictions on the processing of the nodes returned. (The ability of a streaming
                  processor to handle such stylesheets in a streaming manner might, of course,
                  depend on how the nodes returned are processed, but those details are out of scope
                  for this specification.) </p></note></div2><div2 id="stream-examples"><head>Examples of <code nobreak="false">xsl:source-document</code></head><p>The <elcode>xsl:source-document</elcode> instruction can be used to initiate processing of
                  a document using streaming with a variety of coding styles, illustrated in the
                  examples below.</p><example><head>Using <elcode>xsl:source-document</elcode> with Aggregate Functions</head><p>The following example computes the number of transactions in a transaction
                     file</p><p>Input:</p><eg role="xml" xml:space="preserve">
&lt;transactions&gt;
  &lt;transaction value="12.51"/&gt;
  &lt;transaction value="3.99"/&gt;
&lt;/transactions&gt;</eg><p>Stylesheet code:</p><eg xml:space="preserve" role="xslt-instruction">&lt;xsl:source-document streamable="yes" href="transactions.xml"&gt;
  &lt;count&gt;
    &lt;xsl:value-of select="count(transactions/transaction)"/&gt;
  &lt;/count&gt;
&lt;/xsl:source-document&gt;</eg><p>Result:</p><eg role="xml" xml:space="preserve">&lt;count&gt;2&lt;/count&gt;</eg><p>Analysis:</p><olist><item><p>The literal result element <code nobreak="false">count</code> has the same sweep as the
                              <elcode>xsl:value-of</elcode> instruction.</p></item><item><p>The <elcode>xsl:value-of</elcode> instruction has the same sweep as its
                              <code nobreak="false">select</code> expression.</p></item><item><p>The call to <code nobreak="false">count</code> has the same sweep as its argument.</p></item><item><p>The argument to <code nobreak="false">count</code> is a <code nobreak="false">RelativePathExpr</code>.
                           Under the rules in <specref ref="streamability-of-path-expressions"/>,
                           this expression is <termref def="dt-striding"/> and <termref def="dt-consuming"/>. The
                              call on <code nobreak="false">count</code> is therefore <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.
                        </p></item><item><p>The entire body of the <elcode>xsl:source-document</elcode> instruction is therefore
                        <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></item></olist><p>The following example computes the highest-value transaction in the same input
                     file:</p><eg xml:space="preserve" role="xslt-instruction">&lt;xsl:source-document streamable="yes" href="transactions.xml"&gt;
  &lt;maxValue&gt;
    &lt;xsl:value-of select="max(transactions/transaction/@value)"/&gt;
  &lt;/maxValue&gt;
&lt;/xsl:source-document&gt;</eg><p>Result:</p><eg role="xml" xml:space="preserve">&lt;maxValue&gt;12.51&lt;/maxValue&gt;</eg><p>Analysis:</p><olist><item><p>The literal result element <code nobreak="false">maxValue</code> has the same sweep as
                           the <elcode>xsl:value-of</elcode> instruction.</p></item><item><p>The <elcode>xsl:value-of</elcode> instruction has the same sweep as its
                              <code nobreak="false">select</code> expression.</p></item><item><p>The call to <code nobreak="false">max</code> has the same sweep as its argument.</p></item><item><p>The argument to <code nobreak="false">max</code> is a <code nobreak="false">RelativePathExpr</code> whose
                           two operands are the <code nobreak="false">RelativePathExpr</code>
                           <code nobreak="false">transactions/transaction</code> and the <code nobreak="false">AxisStep</code>
                           <code nobreak="false">@value</code>. The left-hand operand <code nobreak="false">transactions/transaction</code> has
                              <termref def="dt-striding"/>
                              <termref def="dt-posture"/>. The right-hand operand <code nobreak="false">@value</code>, given
                           that <phrase diff="chg" at="2022-01-01">the context posture is striding</phrase>, is <termref def="dt-motionless"/>. The <code nobreak="false">RelativePathExpr</code> argument to <code nobreak="false">max</code> is
                           therefore consuming. <!--<phrase diff="add" at="2022-01-01">[XSLT 3.0 Erratum E9, bug 30130].</phrase>--></p></item><item><p>The entire body of the <elcode>xsl:source-document</elcode> instruction is
                           therefore <termref def="dt-consuming"/>.</p></item></olist><p>To compute both the count and the maximum value in a single pass over the
                     input, several approaches are possible. The simplest is to use maps (map constructors
                     are exempt from the usual rule that multiple downward selections are not allowed):</p><eg xml:space="preserve" role="xslt-instruction">&lt;xsl:source-document streamable="yes" href="transactions.xml"&gt;
  &lt;xsl:variable name="tally" select="{ 'count': count(transactions/transaction), 
                                          'max': max(transactions/transaction/@value) }"/&gt;
  &lt;value count="{ $tally('count') }" max="{ $tally('max') }"/&gt;
&lt;/xsl:source-document&gt;</eg><p>Other options include the use of <elcode>xsl:fork</elcode>, or multiple <elcode>xsl:accumulator</elcode>
                  declarations, one for each value to be computed.</p></example><example><head>Using <elcode>xsl:source-document</elcode> with <elcode>xsl:for-each</elcode> to
                     Process a Collection of Input Documents </head><p>This example displays a list of the chapter titles extracted from each book in
                     a collection of books.</p><p>Each input document is assumed to have a structure such as:</p><eg role="xml" xml:space="preserve">&lt;book&gt;
  &lt;chapter number-of-pages="18"&gt;
    &lt;title&gt;The first chapter of book A&lt;/title&gt;
    ...
  &lt;/chapter&gt;
  &lt;chapter number-of-pages="15"&gt;
    &lt;title&gt;The second chapter of book A&lt;/title&gt;
    ...
  &lt;/chapter&gt;
  &lt;chapter number-of-pages="12"&gt;
    &lt;title&gt;The third chapter of book A&lt;/title&gt;
    ...
  &lt;/chapter&gt;
&lt;/book&gt;</eg><p>Stylesheet code:</p><eg xml:space="preserve" role="xslt-fragment">&lt;chapter-titles&gt;
  &lt;xsl:for-each select="uri-collection('books')"&gt;
    &lt;xsl:source-document streamable="yes" href="{.}"&gt;
      &lt;xsl:for-each select="book"&gt;
        &lt;xsl:for-each select="chapter"&gt;
           &lt;title&gt;&lt;xsl:value-of select="title"/&gt;&lt;/title&gt;
        &lt;/xsl:for-each&gt;
      &lt;/xsl:for-each&gt;
    &lt;/xsl:source-document&gt;
  &lt;/xsl:for-each&gt;
&lt;/chapter-titles&gt;</eg><p>Output:</p><eg role="xml" xml:space="preserve">&lt;chapter-titles&gt;
  &lt;title&gt;The first chapter of book A&lt;/title&gt;
  &lt;title&gt;The second chapter of book A&lt;/title&gt;
  ...
  &lt;title&gt;The first chapter of book B&lt;/title&gt;
  ...
&lt;/chapter-titles&gt;</eg><note><p>This example uses the function <xfunction>uri-collection</xfunction> to
                        obtain the document URIs of all the documents in a collection, so that each
                        one can be processed in turn using <elcode>xsl:source-document</elcode>.</p></note></example><example><head>Using <elcode>xsl:source-document</elcode> with <elcode>xsl:iterate</elcode>
                  </head><p>This example assumes that the input is a book with multiple chapters, as shown
                     in the previous example, with the page count for each chapter given as an
                     attribute of the chapter. The transformation determines the starting page
                     number for each chapter by accumulating the page counts for previous chapters,
                     and rounding up to an odd number if necessary.</p><eg xml:space="preserve" role="xslt-fragment">&lt;chapter-start-page&gt;
   &lt;xsl:source-document streamable="yes" href="book.xml"&gt;
      &lt;xsl:iterate select="book/chapter"&gt;
         &lt;xsl:param name="start-page" select="1"/&gt;
         &lt;chapter title="{title}" start-page="{ $start-page }"/&gt;
         &lt;xsl:next-iteration&gt;
            &lt;xsl:with-param name="start-page" 
                            select="$start-page + @number-of-pages + 
                                      (@number-of-pages mod 2)"/&gt;
         &lt;/xsl:next-iteration&gt;
      &lt;/xsl:iterate&gt;
   &lt;/xsl:source-document&gt;
&lt;/chapter-start-page&gt;
</eg><p>Output:</p><eg role="xml" xml:space="preserve">&lt;chapter-start-page&gt;
  &lt;chapter title="The first chapter of book A" start-page="1"/&gt;
  &lt;chapter title="The second chapter of book A" start-page="19"/&gt;
  &lt;chapter title="The third chapter of book A" start-page="35"/&gt;
  ...
&lt;/chapter-start-page&gt;
                     </eg></example><example><head>Using <elcode>xsl:source-document</elcode> with <elcode>xsl:for-each-group</elcode>
                  </head><p>This example assumes that the input is a book with multiple chapters, and that
                     each chapter belongs to a part, which is present as an attribute of the chapter
                     (for example, chapters 1-4 might constitute Part 1, the next three chapters
                     forming Part 2, and so on):</p><eg role="xml" xml:space="preserve">&lt;book&gt;
  &lt;chapter part="1"&gt;
    &lt;title&gt;The first chapter of book A&lt;/title&gt;
    ...
  &lt;/chapter&gt;
  &lt;chapter part="1"&gt;
    &lt;title&gt;The second chapter of book A&lt;/title&gt;
    ...
  &lt;/chapter&gt;
  ...
  &lt;chapter part="2"&gt;
    &lt;title&gt;The fifth chapter of book A&lt;/title&gt;
    ...
  &lt;/chapter&gt;
&lt;/book&gt;</eg><p>The transformation copies the full text of the chapters, creating an extra
                     level of hierarchy for the parts.</p><eg xml:space="preserve" role="xslt-fragment">&lt;book&gt;
   &lt;xsl:source-document streamable="yes" href="book.xml"&gt;
      &lt;xsl:for-each select="book"&gt;
         &lt;xsl:for-each-group select="chapter" group-adjacent="data(@part)"&gt;
            &lt;part number="{current-grouping-key()}"&gt;
               &lt;xsl:copy-of select="current-group()"/&gt;
            &lt;/part&gt;
         &lt;/xsl:for-each-group&gt;
      &lt;/xsl:for-each&gt;
   &lt;/xsl:source-document&gt;
&lt;/book&gt;
</eg><p>Output:</p><eg role="xml" xml:space="preserve">&lt;book&gt;
  &lt;part number="1"&gt;
    &lt;chapter part="1"&gt;
      &lt;title&gt;The first chapter of book A&lt;/title&gt;
      ...
    &lt;/chapter&gt;
    &lt;chapter part="1"&gt;
      &lt;title&gt;The second chapter of book A&lt;/title&gt;
      ...
    &lt;/chapter&gt;
    ...
  &lt;/part&gt;
  &lt;part number="2"&gt;
    &lt;chapter part="2"&gt;
      &lt;title&gt;The fifth chapter of book A&lt;/title&gt;
    ...
    &lt;/chapter&gt;
    ...
  &lt;/part&gt;
&lt;/book&gt;
    </eg></example><example><head>Using <elcode>xsl:source-document</elcode> with <elcode>xsl:apply-templates</elcode>
                  </head><p>This example copies an XML document while deleting all the <code nobreak="false">ednote</code>
                     elements at any level of the tree, together with their descendants. This
                     example is a complete stylesheet, which is intended to be evaluated by
                     nominating <code nobreak="false">main</code> as the <xtermref spec="XT40" ref="dt-initial-named-template"/>.
                     The use of <code nobreak="false">on-no-match="deep-copy"</code> in the
                        <elcode>xsl:mode</elcode> declaration means that the built-in template rule
                     copies nodes unchanged, except where overridden by a user-defined template
                     rule.</p><eg xml:space="preserve" role="xslt-document">&lt;xsl:transform version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

&lt;xsl:mode name="delete-ednotes" streamable="yes" 
                                on-no-match="shallow-copy"/&gt;

&lt;xsl:template name="main"&gt;
   &lt;xsl:source-document streamable="yes" href="book.xml"&gt;
      &lt;xsl:apply-templates mode="delete-ednotes"/&gt;
   &lt;/xsl:source-document&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="ednote" mode="delete-ednotes"/&gt;

&lt;/xsl:transform&gt;</eg><p>Additional template rules could be added to process other elements and
                     attributes in the same pass through the data: for example, to modify the value
                     of a <code nobreak="false">last-updated</code> attribute (wherever it appears) to the current
                     date and time, the following rule suffices:</p><eg xml:space="preserve" role="xslt-declaration">
&lt;xsl:template match="@last-updated" mode="delete-ednotes"&gt;
  &lt;xsl:attribute name="last-updated" select="current-dateTime()"/&gt;
&lt;/xsl:template&gt;</eg></example><!--              <example>
                  <head>Using <elcode>xsl:source-document</elcode> with <elcode>xsl:merge</elcode>
                  </head>
                  <p>This example builds a file representing the index of a book from files
                     containing the index for each chapter. The chapter-level index files contain
                     entries of the form <code>&lt;entry term="XML" page="27"/></code> sorted first
                     alphabetically by term and then numerically by page number; the sort order for
                     the combined index is the same.</p>
                  <eg xml:space="preserve"><![CDATA[<index>
   <xsl:merge>
     <xsl:merge-source select="uri-collection('chapter-indexes')">
         <xsl:source-document streamable="yes" href="{.}">
           <xsl:copy-of select="index/entry"/>
         </xsl:source-document>
         <xsl:merge-key select="string(@term)"/>
         <xsl:merge-key select="xs:integer(@page)"/>
    </xsl:merge-source>
    <xsl:merge-action>
       <xsl:copy-of select="current-group()[1]"/>
    </xsl:merge-action>
  </xsl:merge>
</index>]]></eg>

                  <p>In cases where two chapter indexes contain entries for the same term, they will
                     normally have different page numbers, and will therefore go in separate groups.
                     Their order in the output is based on the ordering of the merge keys, which
                     means entries with the same term appear in page number order. In the unlikely
                     case that two files contain entries where both the term and the page number are
                     the same (or, perhaps more plausibly, where such duplicates occur within a
                     single input file), the <elcode>xsl:merge-action</elcode> ensures that only the
                     first of the duplicates will be copied. </p>
               </example>--></div2></div1><div1 id="streamable-templates"><head>Streamable Templates</head><p>A template rule that is <xtermref spec="XT40" ref="dt-applicable"/> 
                 to a mode <var>M</var> is <termref def="dt-guaranteed-streamable"/> if and only if all the following conditions
                  are satisfied:</p><olist><item><p>Mode <var>M</var> is declared in an <elcode>xsl:mode</elcode> declaration
                        that specifies <code nobreak="false">streamable="yes"</code>.</p></item><item><p>The <xtermref spec="XT40" ref="dt-pattern">pattern</xtermref> defined in the
                           <code nobreak="false">match</code> attribute of the <elcode>xsl:template</elcode> element
                           is a <termref def="dt-motionless"/>
                        pattern as defined in <specref ref="classifying-patterns"/>.</p></item><item><p>The <termref def="dt-sweep"/> of the <xtermref spec="XT40" ref="dt-sequence-constructor"/> 
                       forming the body of the <elcode>xsl:template</elcode> element is either
                           <termref def="dt-motionless"/> or <termref def="dt-consuming"/>.</p></item><item><p>The <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted
                           posture</termref> of the <xtermref spec="XT40" ref="dt-sequence-constructor"/> forming
                        the body of the <elcode>xsl:template</elcode> element, with respect to the
                           <termref def="dt-utype"/> that corresponds to the declared return type of
                        the template (defaulting to <code nobreak="false">item()*</code>), is <termref def="dt-grounded"/>.</p><note><p>This means that either (a) the sequence constructor is grounded as
                           written (that is, it does not return streamed nodes), or (b) it
                           effectively becomes grounded because the declared result type of the
                           template is atomic, leading to implicit atomization of the result.</p></note></item><item><p>Every <xtermref spec="XT40" ref="dt-expression">expression</xtermref> and contained
                           <xtermref spec="XT40" ref="dt-sequence-constructor"/> in a contained
                           <elcode>xsl:param</elcode> element (the construct that provides the
                        default value of the parameter) is
                        <termref def="dt-motionless"/>.</p></item></olist><p>Specifying <code nobreak="false">streamable="yes"</code> on an
                     <elcode>xsl:mode</elcode> declaration declares an intent that every template
                  rule <phrase diff="chg" at="2022-01-01">to which that mode is <xtermref spec="XT40" ref="dt-applicable"/></phrase> 
                  (explicitly or implicitly, including by specifying
                     <code nobreak="false">#all</code>), should be streamable,
                     either because it is <termref def="dt-guaranteed-streamable"/>, or because it
                     takes advantage of streamability extensions offered by a particular
                     processor. The consequences of declaring the mode to be streamable
                  when there is such a template rule that is not guaranteed streamable depend on the
                  conformance level of the processor, and are explained in <specref ref="streamability-guarantees"/>.</p><p>Processing of a document using streamable templates may be
                  initiated using code such as the following, where <code nobreak="false">S</code> is a mode
                  declared with <code nobreak="false">streamable="yes"</code>:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:source-document streamable="yes" href="bigdoc.xml"&gt;
  &lt;xsl:apply-templates mode="S"/&gt;
&lt;/xsl:source-document&gt;</eg><p>Alternatively, streamed processing may be initiated by invoking
                  the transformation with an <xtermref spec="XT40" ref="dt-initial-mode"/> declared as
                  streamable, while supplying the <xtermref spec="XT40" ref="dt-initial-match-selection"/> 
                 (in an <termref def="dt-implementation-defined"/> way) as a streamed document.</p><imp-def-feature id="idf-api-streaming">Streamed processing may be initiated by
                  invoking the transformation with an <xtermref spec="XT40" ref="dt-initial-mode"/> declared as
                  streamable, while supplying the <xtermref spec="XT40" ref="dt-initial-match-selection"/> 
                 (in an <termref def="dt-implementation-defined"/> way) as a streamed
                  document.</imp-def-feature><note><p>Invoking a streamable template using the construct
                        <code nobreak="false">&lt;xsl:apply-templates select="doc('bigdoc.xml')"/&gt;</code> does
                     not ensure streamed processing. As always, processors may use streamed
                     processing if they are able to do so, but when the <xfunction>doc</xfunction>
                     or <function>document</function> functions are used, processors are obliged to
                     ensure that the results are deterministic, which may be difficult to reconcile
                     with streaming (if the same document is read twice, the results must be
                     identical). The use of <elcode>xsl:source-document</elcode> 
                     with <code nobreak="false">streamable="yes"</code>
                     does not offer the same guarantees of determinism.</p></note><p>For an example of processing a collection of documents by use of the function
                     <xfunction>uri-collection</xfunction> in conjunction with
                     <elcode>xsl:source-document</elcode>, see <specref ref="stream-examples"/>.</p></div1><div1 id="streaming-with-xsl-iterate"><head>Streaming with <elcode>xsl:iterate</elcode></head><p>The <elcode>xsl:iterate</elcode> instruction plays an important role in streamed applications,
              because it allows an application (by means of the <elcode>xsl:iterate</elcode> parameters)
              to remember selected information as elements from a streamed source document are processed.</p><note><p>An alternative way of achieving this is with streamed accumulators:
              see <specref ref="streamability-of-accumulators"/>.</p></note><p>The examples below use the <elcode>xsl:iterate</elcode> instruction in conjunction with the
                  <elcode>xsl:source-document</elcode> instruction. This is not the only way of using
                  <elcode>xsl:iterate</elcode>, but it illustrates the way in which the two features
               can be combined to achieve streaming of a large input document.</p><example><head>Using <elcode>xsl:iterate</elcode> to Compute Cumulative Totals</head><p>Suppose that the input XML document has this structure</p><eg xml:space="preserve" role="xml">&lt;transactions&gt;
  &lt;transaction date="2008-09-01" value="12.00"/&gt;
  &lt;transaction date="2008-09-01" value="8.00"/&gt;
  &lt;transaction date="2008-09-02" value="-2.00"/&gt;
  &lt;transaction date="2008-09-02" value="5.00"/&gt;
&lt;/transactions&gt;</eg><p>and that the requirement is to transform this to:</p><eg xml:space="preserve" role="xml">&lt;account&gt;
  &lt;balance date="2008-09-01" value="12.00"/&gt;
  &lt;balance date="2008-09-01" value="20.00"/&gt;
  &lt;balance date="2008-09-02" value="18.00"/&gt;
  &lt;balance date="2008-09-02" value="23.00"/&gt;
&lt;/account&gt;</eg><p>This can be achieved using the following code, which is designed to process the
                  transaction file using streaming:</p><eg xml:space="preserve" role="xslt-fragment">&lt;account&gt;
  &lt;xsl:source-document streamable="yes" href="transactions.xml"&gt;
    &lt;xsl:iterate select="transactions/transaction"&gt;
      &lt;xsl:param name="balance" select="0.00" as="xs:decimal"/&gt;
      &lt;xsl:variable name="newBalance" 
                    select="$balance + xs:decimal(@value)"/&gt;
      &lt;balance date="{@date}" value="{format-number($newBalance, '0.00')}"/&gt;
      &lt;xsl:next-iteration&gt;
        &lt;xsl:with-param name="balance" select="$newBalance"/&gt;
      &lt;/xsl:next-iteration&gt;
    &lt;/xsl:iterate&gt;
  &lt;/xsl:source-document&gt;
&lt;/account&gt;</eg><p>The following example modifies this by only outputting the information for the
                  first day’s transactions:</p><eg xml:space="preserve" role="xslt-fragment">&lt;account&gt;
  &lt;xsl:source-document streamable="yes" href="transactions.xml"&gt;
    &lt;xsl:iterate select="transactions/transaction"&gt;
      &lt;xsl:param name="balance" select="0.00" as="xs:decimal"/&gt;
      &lt;xsl:param name="prevDate" select="()" as="xs:date?"/&gt;
      &lt;xsl:variable name="newBalance" 
                    select="$balance + xs:decimal(@value)"/&gt;
      &lt;xsl:variable name="thisDate" 
                    select="xs:date(@date)"/&gt;
      &lt;xsl:choose&gt;
        &lt;xsl:when test="empty($prevDate) or $thisDate eq $prevDate"&gt;
          &lt;balance date="{ $thisDate }" 
                   value="{ format-number($newBalance, '0.00') }"/&gt;
          &lt;xsl:next-iteration&gt;
            &lt;xsl:with-param name="balance" select="$newBalance"/&gt;
            &lt;xsl:with-param name="prevDate" select="$thisDate"/&gt;
          &lt;/xsl:next-iteration&gt;
        &lt;/xsl:when&gt;
        &lt;xsl:otherwise&gt;
          &lt;xsl:break/&gt;
        &lt;/xsl:otherwise&gt;
      &lt;/xsl:choose&gt;
    &lt;/xsl:iterate&gt;
  &lt;/xsl:source-document&gt;
&lt;/account&gt;</eg><p>The following code outputs the balance only at the end of each day, together with
                  the final balance:</p><eg xml:space="preserve" role="xslt-fragment">&lt;account&gt;
  &lt;xsl:source-document streamable="yes" href="transactions.xml"&gt;
    &lt;xsl:iterate select="transactions/transaction"&gt;
      &lt;xsl:param name="balance" select="0.00" as="xs:decimal"/&gt;
      &lt;xsl:param name="prevDate" select="()" as="xs:date?"/&gt;
      &lt;xsl:on-completion&gt;
        &lt;balance date="{ $prevDate }" 
                 value="{ format-number($balance, '0.00') }"/&gt;
      &lt;/xsl:on-completion&gt;     
      &lt;xsl:variable name="newBalance" 
                    select="$balance + xs:decimal(@value)"/&gt;
      &lt;xsl:variable name="thisDate" select="xs:date(@date)"/&gt;
      &lt;xsl:if test="exists($prevDate) and $thisDate ne $prevDate"&gt;
        &lt;balance date="{ $prevDate }" 
                 value="{ format-number($balance, '0.00') }"/&gt;
      &lt;/xsl:if&gt;
      &lt;xsl:next-iteration&gt;
        &lt;xsl:with-param name="balance" select="$newBalance"/&gt;
        &lt;xsl:with-param name="prevDate" select="$thisDate"/&gt;
      &lt;/xsl:next-iteration&gt;     
    &lt;/xsl:iterate&gt;
  &lt;/xsl:source-document&gt;
&lt;/account&gt;</eg><p>If the sequence of transactions is empty, this code outputs a single element:
                     <code nobreak="false">&lt;balance date="" value="0.00"/&gt;</code>.</p></example><example><head>Collecting Multiple Values in a Single Pass</head><p>Problem: Given a sequence of <code nobreak="false">employee</code> elements, find the employees
                  having the highest and lowest salary, while processing each employee only
                  once.</p><p>Solution:</p><eg xml:space="preserve" role="xslt-instruction">&lt;xsl:source-document streamable="yes" href="employees.xml"&gt;
    &lt;xsl:iterate select="employees/employee"&gt;
        &lt;xsl:param name="highest" as="element(employee)*"/&gt;
        &lt;xsl:param name="lowest" as="element(employee)*"/&gt;
        &lt;xsl:on-completion&gt;
            &lt;highest-paid-employees&gt;
                &lt;xsl:value-of select="$highest/name"/&gt;
            &lt;/highest-paid-employees&gt;
            &lt;lowest-paid-employees&gt;
                &lt;xsl:value-of select="$lowest/name"/&gt;
            &lt;/lowest-paid-employees&gt;  
        &lt;/xsl:on-completion&gt;
        &lt;xsl:variable name="this" select="copy-of()"/&gt;
        &lt;xsl:variable name="is-new-highest" as="xs:boolean"
            select="empty($highest[@salary ge current()/@salary])"/&gt;
        &lt;xsl:variable name="is-equal-highest" as="xs:boolean" 
            select="exists($highest[@salary eq current()/@salary])"/&gt; 
        &lt;xsl:variable name="is-new-lowest" as="xs:boolean" 
            select="empty($lowest[@salary le current()/@salary])"/&gt;
        &lt;xsl:variable name="is-equal-lowest" as="xs:boolean" 
            select="exists($lowest[@salary eq current()/@salary])"/&gt; 
        &lt;xsl:variable name="new-highest-set" as="element(employee)*"
            select="if ($is-new-highest) then $this
            else if ($is-equal-highest) then ($highest, $this)
            else $highest"/&gt;
        &lt;xsl:variable name="new-lowest-set" as="element(employee)*"
            select="if ($is-new-lowest) then $this
            else if ($is-equal-lowest) then ($lowest, $this)
            else $lowest"/&gt;
        &lt;xsl:next-iteration&gt;
            &lt;xsl:with-param name="highest" select="$new-highest-set"/&gt;
            &lt;xsl:with-param name="lowest" select="$new-lowest-set"/&gt;
        &lt;/xsl:next-iteration&gt;
    &lt;/xsl:iterate&gt;
&lt;/xsl:source-document&gt;</eg><p>If the input sequence is empty, this code outputs an empty
                     <code nobreak="false">highest-paid-employees</code> element and an empty
                     <code nobreak="false">lowest-paid-employees</code> element.</p></example><example><head>Processing the Last Item in a Sequence Specially</head><p>When streaming, it is not possible to determine whether the item being processed
                  is the last in a sequence without reading ahead. The <xfunction>last</xfunction>
                  function therefore cannot be used in <xtermref spec="SG40" ref="dt-guaranteed-streamable"/>
                  code. The <elcode>xsl:iterate</elcode> instruction provides a solution to this
                  problem.</p><p>Problem: render the last paragraph in a section in some special way, for example
                  by using bold face. (The actual rendition is achieved by processing the paragraph
                  with mode <code nobreak="false">last-para</code>.)</p><p>The solution uses <elcode>xsl:iterate</elcode>
                  together with the <function>copy-of</function>
                     function to maintain a one-element look-ahead by explicit coding:</p><eg role="xslt-declaration" xml:space="preserve">&lt;xsl:template match="section" mode="streaming"&gt;
   &lt;xsl:iterate select="para"&gt;
     &lt;xsl:param name="prev" select="()" as="element(para)?"/&gt;
     &lt;xsl:on-completion&gt;
       &lt;xsl:apply-templates select="$prev" mode="last-para"/&gt;      
     &lt;/xsl:on-completion&gt;
     &lt;xsl:if test="$prev"&gt;
       &lt;xsl:apply-templates select="$prev"/&gt;
     &lt;/xsl:if&gt;
     &lt;xsl:next-iteration&gt;
       &lt;xsl:with-param name="prev" select="copy-of(.)"/&gt;
     &lt;/xsl:next-iteration&gt;
   &lt;/xsl:iterate&gt;
 &lt;/xsl:template&gt;</eg></example></div1><div1 id="handling-empty-input"><head>Handling Empty Input</head><p>The three instructions <elcode>xsl:where-populated</elcode>,
              <elcode>xsl:on-empty</elcode>, and <elcode>xsl:on-non-empty</elcode>
              were introduced to the language explicitly to make it easier to generate
               result trees conditionally depending on what is found in the input, without violating
               the rules for streamability. These facilities are available whether or not streaming
               is in use. This section provides examples of how they can be used 
               to process streamed input.</p><p>The specific problem tackled by these instructions arises when empty input
            is to be processed differently from non-empty input: for example, outputting the
            message “There are no orders today” rather than an empty list of orders, or
            outputting a subtotal only when the list of items to be totaled is non-empty. The 
            conventional approach to this involves writing something like:</p><eg xml:space="preserve">&lt;xsl:choose&gt;
   &lt;xsl:when test="empty(item)"&gt;There are no orders today!&lt;/xsl:when&gt;
   &lt;xsl:otherwise&gt;&lt;xsl:apply-templates select="item"/&gt;&lt;/xsl:otherwise&gt;
&lt;/xsl:choose&gt;</eg><p>but this is not streamable, because there are two instructions that process the
           child <code nobreak="false">item</code> elements.</p><p>The alternative formulation using <elcode>xsl:on-empty</elcode> is fully
           streamable:</p><eg xml:space="preserve">&lt;xsl:sequence&gt;
   &lt;xsl:apply-templates select="item"/&gt;   
   &lt;xsl:on-empty&gt;There are no orders today!&lt;/xsl:on-empty&gt;
&lt;/xsl:sequence&gt;</eg><p>The examples that follow illustrate how to use these instructions when
              writing streamable stylesheet code.</p><example><head>Generating a Wrapper Element for a non-Empty Sequence</head><p>The following example generates an <code nobreak="false">events</code> element if and only if
                  there are one or more <code nobreak="false">event</code> elements. The code could be written like
                  this:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:if test="exists(event)"&gt;
  &lt;events&gt;
    &lt;xsl:copy-of select="event"/&gt;
  &lt;/events&gt;
&lt;/xsl:if&gt;</eg><p>However, the above code would not be <termref def="dt-guaranteed-streamable"/>,
                  because it processes the child <code nobreak="false">event</code> elements more than once. To make
                  it streamable, it can be rewritten as:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:where-populated&gt;
  &lt;events&gt;
    &lt;xsl:copy-of select="event"/&gt;
  &lt;/events&gt;
&lt;/xsl:where-populated&gt;</eg><p>The effect of the <elcode>xsl:where-populated</elcode> instruction
                  is to avoid outputting the <code nobreak="false">events</code> element if it would have no
                  children. A streaming implementation will typically hold the start tag of the
                     <code nobreak="false">events</code> element in a buffer, to be sent to the output destination
                  only if and when a child node is generated.</p></example><example><head>Generating a Header and Footer only if there is Content</head><p>The following example generates an <code nobreak="false">h3</code> element and a summary paragraph
                  only if a list of items is non-empty. The code could be written like this:</p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:if test="exists(item-for-sale)"&gt;
  &lt;h1&gt;Items for Sale&lt;/h1&gt;
&lt;/xsl:if&gt;  
&lt;xsl:apply-templates select="item-for-sale"/&gt;
&lt;xsl:if test="exists(item-for-sale)"&gt;
  &lt;p&gt;Total value: {accumulator-before('total-value')}&lt;/p&gt;
&lt;/xsl:if&gt;</eg><p>However, the above code would not be <termref def="dt-guaranteed-streamable"/>,
                  because it processes the child <code nobreak="false">item-for-sale</code> elements more than once.
                  To make it streamable, it can be rewritten as:</p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:sequence&gt;
  &lt;xsl:on-non-empty&gt;
    &lt;h1&gt;Items for Sale&lt;/h1&gt;
  &lt;/xsl:on-non-empty&gt;  
  &lt;xsl:apply-templates select="item-for-sale"/&gt;
  &lt;xsl:on-non-empty&gt;
    &lt;p&gt;Total value: {accumulator-before('total-value')}&lt;/p&gt;
  &lt;/xsl:on-non-empty&gt;  
&lt;/xsl:sequence&gt;</eg><p>The effect of the <elcode>xsl:on-non-empty</elcode> instruction
                  is to output the enclosed content only if the containing sequence
                  constructor also generates “ordinary” content, that is, if there is content
                  generated by instructions other than <elcode>xsl:on-empty</elcode> and
                     <elcode>xsl:on-non-empty</elcode> instructions.</p></example><example><head>Generating Substitute Text when there is no Content</head><p>The following example generates a summary paragraph only if a list of items is
                  empty. The code could be written like this:</p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:apply-templates select="item-for-sale"/&gt;
&lt;xsl:if test="empty(item-for-sale)"&gt;
  &lt;p&gt;There are no items for sale.&lt;/p&gt;
&lt;/xsl:if&gt;</eg><p>However, the above code would not be <termref def="dt-guaranteed-streamable"/>,
                  because it processes the child <code nobreak="false">item-for-sale</code> elements more than once
                  (the fact that the list is empty is irrelevant, because streamability is
                  determined statically). To make the code streamable, it can be rewritten as:</p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:sequence&gt;
  &lt;xsl:apply-templates select="item-for-sale"/&gt;
  &lt;xsl:on-empty&gt;
    &lt;p&gt;There are no items for sale.&lt;/p&gt;
  &lt;/xsl:on-empty&gt;
&lt;/xsl:sequence&gt;</eg><p>The effect of the <elcode>xsl:on-empty</elcode> instruction
                  is to output the enclosed content only if the containing sequence constructor
                  generates no “ordinary” content, that is, if there is no content generated by
                  instructions other than <elcode>xsl:on-empty</elcode> and
                     <elcode>xsl:on-non-empty</elcode> instructions.</p></example><note><p>In some cases, similar effects can be achieved by using the
                     <xfunction>has-children</xfunction> function, which tests whether an element
                  has child nodes without consuming the children. However, use of
                     <xfunction>has-children</xfunction> has the drawback that the function is
                  unselective: it cannot be used to test whether there are any children of relevance
                  to the application. In particular, it returns <code nobreak="false">true</code> if an element contains comments
                  or whitespace text nodes that the application might consider to be
                  insignificant.</p></note><note><p>There are no special streamability rules for the three instructions
                     <elcode>xsl:where-populated</elcode>, <elcode>xsl:on-empty</elcode>, or
                     <elcode>xsl:on-non-empty</elcode>. The <termref def="dt-general-streamability-rules"/> apply. 
                 In many cases the
                     <elcode>xsl:on-empty</elcode> and <elcode>xsl:on-non-empty</elcode>
                  instructions will generate content that does not depend on the source document,
                  and they will therefore be <termref def="dt-motionless"/>, but this is not
                  required.</p></note><example><head>Generating an HTML list</head><p>The following example generates an HTML unnumbered list, if and only if the
                     list is non-empty. Note that the presence of the <code nobreak="false">class</code> attribute
                     does not make the list non-empty. The code is written to be streamable.</p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:where-populated expand-text="yes"&gt;
  &lt;ul class="my-list"&gt;
    &lt;xsl:for-each select="source-item"&gt;
       &lt;li&gt;{.}&lt;/li&gt;
    &lt;/xsl:for-each&gt;
  &lt;/ul&gt;
&lt;/xsl:where-populated&gt;</eg></example><example><head>A More Complex Example</head><p>This example shows how the three instructions
                  <elcode>xsl:where-populated</elcode>, <elcode>xsl:on-empty</elcode>, and
                     <elcode>xsl:on-non-empty</elcode> may be combined.</p><p>The example generates a table containing the names and ages of a set
                     of students; if there are no students, it substitutes a paragraph explaining
                     this.</p><eg role="xslt-fragment" xml:space="preserve">&lt;div id="students" xsl:expand-text="yes"&gt;
&lt;xsl:where-populated&gt;
   &lt;table&gt;
      &lt;xsl:on-non-empty&gt;
         &lt;thead&gt;
            &lt;tr&gt;&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Age&lt;/th&gt;&lt;/tr&gt;
         &lt;/thead&gt;
      &lt;/xsl:on-non-empty&gt;
      &lt;xsl:where-populated&gt;
         &lt;tbody&gt;
            &lt;xsl:for-each select="student/copy-of()"&gt;
               &lt;tr&gt;
                  &lt;td&gt;{name}&lt;/td&gt;
                  &lt;td&gt;{age}&lt;/td&gt;
               &lt;/tr&gt;
            &lt;/xsl:for-each&gt;
         &lt;/tbody&gt;
      &lt;/xsl:where-populated&gt;
   &lt;/table&gt;
&lt;/xsl:where-populated&gt;
&lt;xsl:on-empty&gt;
   &lt;p&gt;There are no students&lt;/p&gt;
&lt;/xsl:on-empty&gt;
&lt;/div&gt;</eg><p>Explanation:</p><ulist><item><p>The <elcode>xsl:where-populated</elcode> around the <code nobreak="false">table</code>
                           element ensures that if there is no <code nobreak="false">thead</code> and no
                              <code nobreak="false">tbody</code>, then there will be no <code nobreak="false">table</code>. </p></item><item><p>The <elcode>xsl:on-non-empty</elcode> surrounding the <code nobreak="false">thead</code>
                           element ensures that the <code nobreak="false">thead</code> element is not output unless
                           the <code nobreak="false">tbody</code> element is output. </p></item><item><p>The <elcode>xsl:where-populated</elcode> around the <code nobreak="false">tbody</code>
                           element ensures that the <code nobreak="false">tbody</code> element is not output unless
                           there is at least one table row (<code nobreak="false">tr</code>). </p></item><item><p>The <elcode>xsl:on-empty</elcode> around the <code nobreak="false">p</code> element
                           ensures that if no <code nobreak="false">table</code> is output, then the paragraph
                           <code nobreak="false">There are no students</code> is output instead. </p></item></ulist></example><div2 id="evaluating-on-empty"><head>Streamed Evaluation of <elcode>xsl:on-empty</elcode> and <elcode>xsl:on-non-empty</elcode></head><p>The following non-normative algorithm explains one possible strategy for streamed
                  evaluation of a <xtermref spec="XT40" ref="dt-sequence-constructor"/> containing
                     <elcode>xsl:on-empty</elcode> and/or <elcode>xsl:on-non-empty</elcode>
                  instructions.</p><p>The algorithm makes use of the following mutable variables:</p><ulist><item><p><var>L</var> : a list of instructions awaiting evaluation. Initially
                        empty.</p></item><item><p><var>R</var> : a list of items to act as the result of the evaluation.
                        Initially empty.</p></item><item><p><var>F</var> : a boolean flag, initially <code nobreak="false">false</code>, to indicate whether any
                           <xtermref spec="XT40" ref="dt-vacuous">non-vacuous</xtermref> items have been written to <var>R</var> by
                           <term>ordinary instructions</term>. The term <term>ordinary instruction</term>
                        means any node in the sequence constructor other than an
                           <elcode>xsl:on-empty</elcode> or <elcode>xsl:on-non-empty</elcode>
                        instruction.</p></item></ulist><p>The algorithm is as follows:</p><olist><item><p>The nodes in the sequence constructor are evaluated in document order.</p></item><item><p>When an <elcode>xsl:on-non-empty</elcode> instruction is encountered,
                        then:</p><olist><item><p>If <var>F</var> is true, the instruction is evaluated and the result
                              is appended to <var>R</var>.</p></item><item><p>Otherwise, the instruction is appended to <var>L</var>.</p></item></olist></item><item><p>When an <term>ordinary instruction</term> is evaluated:</p><olist><item><p>The results of the evaluation are appended to <var>R</var>, in
                              order.</p></item><item><p>When a <xtermref spec="XT40" ref="dt-vacuous">non-vacuous</xtermref> item is about to be appended to
                                 <var>R</var>, and <var>F</var> is false, then before appending the
                              item to <var>R</var>, the following actions are taken:</p><olist><item><p>Any <elcode>xsl:on-non-empty</elcode> instructions in
                                       <var>L</var> are evaluated, in order, and their results are
                                    appended to <var>R</var>.</p></item><item><p><var>F</var> is set to <code nobreak="false">true</code>.</p></item></olist></item></olist></item><item><p>When an <elcode>xsl:on-empty</elcode> instruction is encountered, then:</p><olist><item><p>If <var>F</var> is true, the instruction is ignored.</p></item><item><p>Otherwise, the existing contents of <var>R</var> are discarded, 
                              the instruction is evaluated, and its results are appended to <var>R</var>.</p><note><p>The need to discard items from <var>R</var> 
                              arises only when all the items in <var>R</var> are <xtermref spec="XT40" ref="dt-vacuous"/>. 
                              Streaming implementations may therefore need a limited amount of buffering to retain 
                              insignificant items until it is known whether they will be needed. 
                              However, in many common cases an optimized implementation will be able 
                              to discard <xtermref spec="XT40" ref="dt-vacuous"/> items such as empty text nodes immediately, 
                              because when a node is being constructed using the rules in 
                              <xspecref spec="XT40" ref="constructing-complex-content"/> 
                              or <xspecref spec="XT40" ref="constructing-simple-content"/>, 
                              such items have no effect on the final outcome.</p></note><p>Otherwise, the instruction is evaluated and its results are appended
                              to <var>R</var>.</p></item></olist></item><item><p>The result of the sequence constructor is the list of items in
                        <var>R</var>.</p></item></olist></div2></div1><div1 id="streamability-of-stylesheet-functions"><head>Streamable Stylesheet Functions</head><p>The <code nobreak="false">streamability</code> attribute of <elcode>xsl:function</elcode> is used
                  to assign the function to one of a number of <termref def="dt-streamability-category">streamability categories</termref>. The various
                  categories, and their effect on the streamability of function calls, are described
                  in <specref ref="streamable-stylesheet-functions"/>.</p><p>The streamability category of a function characterizes the way in which the
                  function processes any streamed nodes supplied in the first argument to the
                  function. (In general, streamed nodes cannot be supplied in other arguments,
                  unless they are atomized by the <xtermref spec="XT40" ref="dt-coercion-rules"/>.)
                  The <code nobreak="false">streamability</code> attribute is therefore not applicable unless the
                  function takes at least one argument.</p><p><error spec="XT" type="static" class="SE" code="3155"><p>It is a static error if an <elcode>xsl:function</elcode> element with no
                           <elcode>xsl:param</elcode> children has a <code nobreak="false">streamability</code>
                        attribute with any value other than <code nobreak="false">unclassified</code>.</p></error></p><div2 id="streamable-stylesheet-functions"><head>Classifying Stylesheet Functions</head><p>Under specific conditions, described in this section, a stylesheet function can be
                  used to process nodes from a <termref def="dt-streamed-document">streamed input
                     document</termref>.</p><p><termdef id="dt-streamability-category" term="streamability category">Stylesheet
                     functions belong to one of a number of <term>streamability categories</term>:
                     the choice of category characterizes the way in which the function handles
                     streamed input.</termdef></p><p>The <termref def="dt-streamability-category">category</termref> to which a
                  function belongs is declared in the <code nobreak="false">streamability</code> attribute of the
                     <elcode>xsl:function</elcode> declaration, and defaults to
                     <code nobreak="false">unclassified</code>.</p><p>The streamability categories defined in this specification are:
                     <code nobreak="false">unclassified</code>, <code nobreak="false">absorbing</code>, <code nobreak="false">inspection</code>,
                     <code nobreak="false">filter</code>, <code nobreak="false">shallow-descent</code>, <code nobreak="false">deep-descent</code>,
                  and <code nobreak="false">ascent</code>. It is also possible to specify the streamability category
                  as a QName in an <termref def="dt-implementation-defined"/> namespace, in which
                  case the streamability rules are <termref def="dt-implementation-defined"/>; a
                  processor that does not recognize a category defined in this way
                     <rfc2119>must</rfc2119> analyze the function as if
                     <code nobreak="false">streamability="unclassified"</code> were specified. </p><imp-def-feature id="idf-ext-streamingcategories">Additional <termref def="dt-streamability-category">streamability categories</termref> for
                  stylesheet functions may be defined by an implementation.</imp-def-feature><p>A stylesheet function is <termref def="dt-declared-streamable"/> if the
                     <elcode>xsl:function</elcode> declaration has a <code nobreak="false">streamability</code>
                  attribute with a value other than <code nobreak="false">unclassified</code>.</p><p>The only <termref def="dt-streamability-category">category</termref> permitted for
                  a zero-arity function (one with no arguments) is <code nobreak="false">unclassified</code>. All
                  function calls to zero-arity stylesheet functions are <termref def="dt-grounded"/>
                  and <termref def="dt-motionless"/>.</p><p>In general (subject to more detailed rules below), a node belonging to a <termref def="dt-streamed-document"/> can be present within the value of an argument of
                  a call on a <xtermref spec="XT40" ref="dt-stylesheet-function"/> only if one of the following
                  conditions is true:</p><olist><item><p>The stylesheet function is <termref def="dt-declared-streamable"/>, and the
                        argument in question is the first argument of the function call.</p></item><item><p>The corresponding <xtermref spec="XT40" ref="dt-function-parameter"/> is declared with a
                           <xtermref spec="XT40" ref="dt-required-type"/> that triggers 
                       <xtermref spec="XT40" ref="dt-atomization">atomization</xtermref> of any supplied node.</p></item></olist><p><termdef id="dt-streaming-parameter" term="streaming parameter">The first 
                 <xtermref spec="XT40" ref="dt-function-parameter">parameter</xtermref> of a 
                 <termref def="dt-declared-streamable"/>
                     <xtermref spec="XT40" ref="dt-stylesheet-function"/> is referred to as a <term>streaming
                        parameter</term>.</termdef></p><note><p>If a stylesheet function returns streamed nodes, then these nodes can only
                     derive from streamed nodes passed in an argument to the function. This is
                     because streamed nodes cannot be bound to global variables, and they cannot be
                     returned by an <elcode>xsl:source-document</elcode> instruction within the function body
                     (the result of <elcode>xsl:source-document</elcode> is always grounded).</p></note><p>The choice of <termref def="dt-streamability-category">category</termref> places
                  constraints on the function body, and also on calls to the function. These constraints
                  are defined below, separately for each category. A function is <termref def="dt-guaranteed-streamable"/> only if the constraints are satisfied,
                and a static function call is
               guaranteed-streamable only if the function is guaranteed-streamable and the
               function call itself satisfies the constraints for the chosen category.</p><p>Dynamic function calls are <termref def="dt-guaranteed-streamable"/> only
   in trivial cases, for example where the function signature indicates that an argument is required to
   be a text node or an attribute node. For details, see <specref ref="streamability-of-dynamic-function-calls"/>.</p><p>The constraints on the function body are expressed in terms of the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the function result. The
                     <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the function
                  result are the <termref def="dt-type-adjusted-posture-and-sweep"/> of the <xtermref spec="XT40" ref="dt-sequence-constructor"/> contained within the
                     <elcode>xsl:function</elcode> element, given the declared return type of the
                  function, which defaults to <code nobreak="false">item()*</code>.</p><note><p>Determining the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                     the function result requires first determining the <termref def="dt-posture"/>
                     and <termref def="dt-sweep"/> of the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>, which is done according to the rules in
                        <specref ref="classifying-sequence-constructors"/>. This in turn will
                     usually involve examination of variable references that are bound to the
                     function’s parameters. The analysis of these variable references is described
                     in <specref ref="streamability-of-variable-references"/>.</p></note><p>If the function is <termref def="dt-declared-streamable"/> but does not satisfy
                  the constraints that make it <termref def="dt-guaranteed-streamable"/>, the
                  consequences are explained in <specref ref="streamability-guarantees"/>.</p><p>If a stylesheet function is overridden in another package (using
                     <elcode>xsl:override</elcode>), then the overriding stylesheet function must
                  belong to the same <termref def="dt-streamability-category"/> as the function that
                  it overrides. This ensures that overriding a function cannot affect the
                  streamability of calls to that function.</p><p>The rules for each <termref def="dt-streamability-category"/> are given in the
                  following sections.</p><div3 id="category-unclassified"><head>Streamability Category: unclassified</head><p><term>Informal description:</term> Functions in this category cannot be called
                     with streamed nodes supplied in an argument, unless the function signature
                     causes such nodes to be atomized.</p><p><term>Rules for the function signature:</term> there are no constraints.</p><p><term>Rules for the function body:</term> there are no constraints.</p><p><term>Rules for references to the streaming
                        parameter:</term> not applicable, because there is no streaming
                     parameter.</p><p><term>Rules for function calls:</term> the <termref def="dt-general-streamability-rules"/> apply. The operands are the
                     expressions appearing in the argument list of the function call, with the
                        <termref def="dt-operand-usage"/> of each operand being the <termref def="dt-type-determined-usage"/> based on the declared type of the
                     corresponding parameter in the function signature. </p><example><head>An unclassified stylesheet function that accepts nodes</head><p>The <termref def="dt-streamability-category"/> is
                        <code nobreak="false">unclassified</code>.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:exclude-first" as="node()*"&gt;
  &lt;xsl:param name="nodes" as="node()*"/&gt;
  &lt;xsl:sequence select="$nodes[not(node-name() = preceding-sibling::*/node-name())]"/&gt;
&lt;/xsl:function&gt;  
                        </eg><p>The effect of the rules is that a call to this function is guaranteed
                        streamable if and only if the sequence supplied as the value of the
                           <code nobreak="false">$nodes</code> argument is <termref def="dt-grounded"/> (that is, it
                        contains no streamed nodes).</p></example><example><head>An unclassified stylesheet function that accepts atomic items</head><p>The <termref def="dt-streamability-category"/> is
                        <code nobreak="false">unclassified</code>.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:min" as="xs:integer"&gt;
  &lt;xsl:param name="arg0" as="xs:integer"/&gt;
  &lt;xsl:param name="arg1" as="xs:integer"/&gt;
  &lt;xsl:sequence select="min(($arg0, $arg1))"/&gt;
&lt;/xsl:function&gt;  
                        </eg><p>The effect of the rules is that a call to this function is streamable under
                        similar circumstances to those that apply to a binary operator such as
                           <code nobreak="false">+</code>. For example, a call is streamable if two atomic items
                        are supplied, or if two attribute nodes are supplied, whether from streamed
                        or unstreamed documents. The main constraint is that it is not permitted for
                        both arguments to be consuming; for example, if the context node is a node
                        in a streamed document, then the function call <code nobreak="false">f:min((price,
                           discount))</code> would not be guaranteed streamable.</p></example></div3><div3 id="category-absorbing"><head>Streamability Category: absorbing</head><p><term>Informal description:</term> Functions in this category typically read
                     the subtrees rooted at the node or nodes supplied in the first argument. These
                     subtrees must not overlap each other. The function must not return any streamed
                     nodes.</p><p><term>Rules for the function signature:</term> there are no constraints.</p><p><term>Rules for the function body:</term> 
                     For the function to be <termref def="dt-guaranteed-streamable"/>, the 
                     <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted posture</termref> of
                     the function body with respect to the declared return type must be <termref def="dt-grounded"/>, and the 
                     <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted sweep</termref> of the function body 
                     with respect to the declared return type must be <termref def="dt-motionless"/> or <termref def="dt-consuming"/>.</p><p><term>Rules for references to the streaming
                        parameter:</term> If the declared type of the <termref def="dt-streaming-parameter"/> permits more than one node, then a variable
                     reference referring to the streaming parameter is <termref def="dt-striding"/>
                     and <termref def="dt-consuming"/>. Otherwise such a variable reference is
                        <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p><p><term>Rules for function calls:</term> If the first argument is <termref def="dt-crawling"/> then the function call is <termref def="dt-roaming"/>
                     and <termref def="dt-free-ranging"/>; otherwise the <termref def="dt-general-streamability-rules"/> apply. The operands are the
                     expressions appearing in the argument list of the function call. The <termref def="dt-operand-usage"/> of the first argument is <termref def="dt-absorption"/>; the operand usage of other arguments is the <termref def="dt-type-determined-usage"/> based on the declared type of the
                     corresponding <xtermref spec="XT40" ref="dt-parameter"/> in the function signature. </p><note><p>Absorbing functions perform an operation analogous to atomization on their
                        supplied arguments, in that they typically use information from the subtree
                        rooted at a node to compute atomic items. Atomization can be seen as a
                        special case of absorption. Calls on absorbing functions are therefore, from
                        a streamability point of view, equivalent to calls on functions that
                        implicitly atomize the supplied nodes.</p><p>An important difference, however, is that whereas atomization can be applied
                        to any argument of a function call, absorption applies only to the first
                        argument.</p><p>Another difference is that atomization is allowed on a sequence of nodes in
                           <termref def="dt-crawling"/> posture, whereas generalized absorption is
                        not. Within a sequence, there may be nodes whose subtrees overlap, and the
                        code for atomization is expected to handle this, but more general absorption
                        operations are not. To write a function that accepts streamed nodes and
                        atomizes them, it is better to use the streamability category
                           <code nobreak="false">unclassified</code>, and to declare the first argument with an
                        atomic type, rather than using the category <code nobreak="false">absorbing</code> which
                        allows more general processing, but restricts what can be supplied in the
                        argument to the function call.</p></note><example><head>An absorbing stylesheet function</head><p>The following function is declared as absorbing, and the function body meets
                        the rules for this category because it makes downward selections only, and
                        returns an atomic item.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:count-descendants" as="xs:integer" streamability="absorbing"&gt;
  &lt;xsl:param name="input" as="node()*"/&gt;
  &lt;xsl:sequence select="count($input//*)"/&gt;
&lt;/xsl:function&gt;  
                        </eg><p>The effect of the rules is that a call to this function is <termref def="dt-guaranteed-streamable"/> provided that the sequence supplied as
                        the value of the <code nobreak="false">$input</code> argument is <termref def="dt-motionless"/> or <termref def="dt-consuming"/>, and is either
                           <termref def="dt-grounded"/> or <termref def="dt-striding"/>.</p></example><example><head>An absorbing stylesheet function with two arguments</head><p>The following function is declared as absorbing, and the function body meets
                        the rules for this category because it makes downward selections only from
                        the node supplied as the first argument, and returns an atomic item.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:compare-size" as="xs:integer" streamability="absorbing"&gt;
  &lt;xsl:param name="input0" as="node()"/&gt;
  &lt;xsl:param name="input1" as="node()"/&gt;
  &lt;xsl:sequence select="count($input0//*) - count($input1//*)"/&gt;
&lt;/xsl:function&gt;</eg><p>This function takes two nodes as its arguments. Some examples of function
                        calls include: </p><ulist><item><p>Streamable: <code nobreak="false">f:compare-size(a, b)</code> where <code nobreak="false">a</code> is
                              an element in a streamed document and <code nobreak="false">b</code> is an element in
                              an unstreamed document</p></item><item><p>Streamable: <code nobreak="false">f:compare-size(a, b)</code> where <code nobreak="false">a</code> and
                                 <code nobreak="false">b</code> are both elements in unstreamed documents</p></item><item><p>Not streamable: <code nobreak="false">f:compare-size(a, b)</code> where <code nobreak="false">a</code>
                              is an element in an unstreamed document and <code nobreak="false">b</code> is an
                              element in a streamed document</p></item></ulist><p>The reason for the asymmetry is that for the first
                     argument the <termref def="dt-operand-usage"/> is <termref def="dt-absorption"/>,
                     while for the second argument it is <termref def="dt-navigation"/>. It is a consequence
                     of the <termref def="dt-general-streamability-rules"/> that when streamed nodes are
                     supplied to an operand with usage navigation, the resulting expression is
                     <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></example><example><head>A recursive absorbing stylesheet function</head><p>The following function is declared as absorbing, and the function body meets
                        the rules for this category. Analysis of the function body reveals that it
                        is grounded and consuming; to establish this, it is necessary to analyze the
                        recursive call <code nobreak="false">f:outline(*)</code>, and this is possible because it is
                        known to be a call on an absorbing stylesheet function.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:outline" as="xs:string" streamability="absorbing"&gt;
  &lt;xsl:param name="input" as="element()*"/&gt;
  &lt;xsl:value-of select="$input ! (name() || '(' || f:outline(*) || ')')" 
                separator=", "/&gt;
&lt;/xsl:function&gt;</eg><p>The effect of the rules is that a call to this function is guaranteed
                        streamable in the typical case where the sequence supplied as the value of
                        the <code nobreak="false">$input</code> argument is <termref def="dt-striding"/> and
                           <termref def="dt-consuming"/>.</p></example></div3><div3 id="category-inspection"><head>Streamability Category: inspection</head><p><term>Informal description:</term> Functions in this category typically return
                     properties of the node supplied in the first argument, where these properties
                     can be determined without advancing the input stream. This allows access to
                     properties such as the name and type of each node, and also to its ancestors,
                     attributes, and namespaces. </p><p><term>Rules for the function signature:</term> If
                     the declared type of the streaming parameter permits more than one node,
                     the function is not <termref def="dt-guaranteed-streamable"/>.</p><p><term>Rules for the function body:</term>
                     For the function to be <termref def="dt-guaranteed-streamable"/>, 
                     the <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted posture</termref> of
                     the function body with respect to the declared return type must be <termref def="dt-grounded"/>, and the 
                     <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted sweep</termref> of the function body 
                     with respect to the declared return type must be <termref def="dt-motionless"/>.</p><p><term>Rules for references to the streaming
                        parameter:</term> Such a variable reference is
                        <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p><p><term>Rules for function calls:</term> the <termref def="dt-general-streamability-rules"/> apply. The operands are the
                     expressions appearing in the argument list of the function call. The <termref def="dt-operand-usage"/> of the first argument is <termref def="dt-inspection"/>; the operand usage of other arguments is the <termref def="dt-type-determined-usage"/> based on the declared type of the
                     corresponding argument in the function signature. </p><note><p>The <termref def="dt-streaming-parameter"/> is restricted to be a single
                        node because if <code nobreak="false">$input</code> were a sequence of nodes, then an
                        expression such as <code nobreak="false">($input/name(), $input/@id)</code> would not be
                        streamable.</p></note><example><head>Example of an inspection stylesheet function</head><p>The following function is declared with category <code nobreak="false">inspection</code>,
                        and the function body meets the rules for this category because all
                        references to the supplied node are motionless.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:depth" as="xs:integer" streamability="inspection"&gt;
  &lt;xsl:param name="input" as="node()"/&gt;
  &lt;xsl:sequence select="count($input/ancestor-or-self::*)"/&gt;
&lt;/xsl:function&gt;</eg><p>The effect of the rules is that a call to this function is guaranteed
                        streamable provided that the expression supplied as the value of the
                           <code nobreak="false">$input</code> argument is <termref def="dt-motionless"/> or
                           <termref def="dt-consuming"/>.</p></example><example><head>Example of an inspection stylesheet function with two arguments</head><p>The following function is declared with category <code nobreak="false">inspection</code>,
                        and the function body meets the rules for this category because the function
                        signature ensures that the second argument cannot be a node.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:get-attribute-value" as="xs:string"&gt;
  &lt;xsl:param name="element" as="node()"/&gt;
  &lt;xsl:param name="attribute-name" as="xs:string"/&gt;
  &lt;xsl:sequence select="string($element/@*[local-name() = $attribute-name])"/&gt;
&lt;/xsl:function&gt;</eg><p>Although the normal usage of this function might be to supply an element
                        from a streamed document as the first argument, and a literal string as the
                        second, it is also permissible (and guaranteed streamable) to supply an
                        unstreamed element as the first argument, and an element node from a
                        streamed document as the second. When applying the general streamability
                        rules in this case, the first operand is grounded and motionless, while the
                        second is grounded and consuming (by virtue of the rules for type-determined
                        usage), and this makes the function call grounded and consuming.</p></example></div3><div3 id="category-filter"><head>Streamability Category: filter</head><p><term>Informal description:</term> Functions in this category typically return
                     either the node supplied in the first argument or nothing, depending on the
                     values of properties that can be determined without advancing the input stream.
                     This allows access to properties such as the name and type of each node, and
                     also to its ancestors, attributes, and namespaces. </p><p><term>Rules for the function signature:</term> If
                     the declared type of the streaming parameter permits more than one node,
                     the function is not <termref def="dt-guaranteed-streamable"/>.</p><p><term>Rules for the function body:</term> 
                     For the function to be <termref def="dt-guaranteed-streamable"/>, 
                     the <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted posture</termref> of
                     the function body with respect to the declared return type must be <termref def="dt-striding"/>, and the 
                     <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted sweep</termref> of the function body 
                     with respect to the declared return type must be <termref def="dt-motionless"/>.</p><p><term>Rules for references to the streaming
                        parameter:</term> Such a variable reference is
                        <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p><p><term>Rules for function calls:</term> The <termref def="dt-posture"/> and
                        <termref def="dt-sweep"/> of a call to a function in this category are
                     determined by applying the <termref def="dt-general-streamability-rules"/>. The
                     operands are the expressions supplied as arguments to the function call. The
                     first argument has <termref def="dt-operand-usage"/>
                     <termref def="dt-transmission"/>; any further arguments have <termref def="dt-type-determined-usage"/> based on the declared type of the
                     corresponding parameter in the function signature.</p><example><head>Example of a filtering stylesheet function</head><p>The following function is declared as filtering, and the function body meets
                        the rules for this category because it selects nodes from the input based on
                        motionless properties (namely, the existence of attributes).</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:large-regions" as="element(region)" streamability="filter"&gt;
  &lt;xsl:param name="input" as="element(region)"/&gt;
  &lt;xsl:sequence select="$input[@size gt 1000]"/&gt;
&lt;/xsl:function&gt;</eg><p>The effect of the rules is that the posture and sweep of a function call 
                        <code nobreak="false">f:large-regions(EXPR)</code> are the same as the posture and sweep of <code nobreak="false">EXPR</code>.</p><p>Although the name <code nobreak="false">filter</code> suggests that the result must always
                        be a subset of the input, this is not strictly required by the rules. The
                        function can also return atomic items, as well as attribute and namespace
                        nodes.</p></example></div3><div3 id="category-shallow-descent"><head>Streamability Category: shallow-descent</head><p><term>Informal description:</term> Functions in this category typically return
                     children of the nodes supplied in the first argument. They may also select
                     deeper in the subtrees of these nodes, provided that no node in the result can
                     possibly be an ancestor of any other node in the result. </p><p><term>Rules for the function signature:</term> If
                     the declared type of the streaming parameter permits more than one node,
                     the function is not <termref def="dt-guaranteed-streamable"/>.</p><p><term>Rules for the function body:</term> 
                     For the function to be <termref def="dt-guaranteed-streamable"/>, 
                     the <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted posture</termref> of
                     the function body with respect to the declared return type must be <termref def="dt-striding"/>, and the 
                     <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted sweep</termref> of the function body 
                     with respect to the declared return type must be <termref def="dt-motionless"/> or <termref def="dt-consuming"/>.</p><p><term>Rules for references to the streaming
                        parameter:</term> Such a variable reference is
                        <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p><p><term>Rules for function calls:</term> The rules are as follows, in order:</p><olist><item><p>Let <var>T0</var> be the <termref def="dt-utype"/> corresponding to the
                           declared type of the <termref def="dt-streaming-parameter"/> in the
                           function signature (defaulting to <var>U{*}</var>).</p></item><item><p>Let <var>P0</var> and <var>S0</var> be the <termref def="dt-type-adjusted-posture-and-sweep"/> of the first argument
                           expression, based on type <var>T0</var>.</p></item><item><p>If <var>P0</var> is not <termref def="dt-striding"/> or <termref def="dt-grounded"/>, the function call is <termref def="dt-roaming"/>
                           and <termref def="dt-free-ranging"/>.</p></item><item><p>Consider a construct <var>C</var> whose operands are the argument
                           expressions other than the first argument, with <termref def="dt-type-determined-usage">type-determined operand usage</termref>
                           based on the declared type of the corresponding parameter in the function
                           signature. Let <var>P1</var> and <var>S1</var> be the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of <var>C</var>,
                           assessed using the <termref def="dt-general-streamability-rules"/>.</p><note><p>If there is only one argument, then <var>P1</var> is <termref def="dt-grounded"/> and <var>S1</var> is <termref def="dt-motionless"/>.</p></note></item><item><p>If <var>P1</var> is not <termref def="dt-grounded"/>, the function call
                           is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If <var>S0</var> and <var>S1</var> are both <termref def="dt-consuming"/>, or if either is <termref def="dt-free-ranging"/>, then the function
                           call is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If <var>P0</var> is <termref def="dt-grounded"/>, then the <termref def="dt-posture"/> of the function call is <termref def="dt-grounded"/>, and the <termref def="dt-sweep"/> of the function call is the wider
                           of <var>S0</var> and <var>S1</var>.</p></item><item><p>Otherwise, the <termref def="dt-posture"/> of the function call is
                              <var>P0</var>, and the <termref def="dt-sweep"/> of the function call
                           is as follows:</p><olist><item><p>If the intersection of <var>T0</var> with
                                       <var>U{document-node(), element()}</var> is empty (that is,
                                    the declared type of the first argument does not permit document
                                    or element nodes) then <var>S0</var>.</p></item><item><p>Let <var>A</var> be the <termref def="dt-static-type"/> of the
                                    expression supplied as the first argument. If the intersection
                                    of <var>A</var> with <var>U{document-node(), element()}</var> is
                                    empty (that is, the inferred type of the expression supplied as
                                    the first argument does not permit document or element nodes)
                                    then <var>S0</var>.</p></item><item><p>Otherwise, <termref def="dt-consuming"/>.</p></item></olist></item></olist><example><head>A shallow-descent stylesheet function</head><p>The following function is declared as shallow-descent, and the function body
                        meets the rules for this category because it selects children of the
                        supplied input node.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:alternate-children" as="node()*" 
                                          streamability="shallow-descent"&gt;
  &lt;xsl:param name="input" as="element()"/&gt;
  &lt;xsl:sequence select="$input/node()[position() mod 2 = 1]"/&gt;
&lt;/xsl:function&gt;</eg><p>The effect of the rules is that a call to this function is guaranteed
                        streamable in the typical case where the node supplied as the value of
                        the <code nobreak="false">$input</code> argument is <termref def="dt-striding"/> and
                           <termref def="dt-consuming"/>.</p></example></div3><div3 id="category-deep-descent"><head>Streamability Category: deep-descent</head><p><term>Informal description:</term> Functions in this category typically return
                     descendants of the nodes supplied in the first argument. </p><p><term>Rules for the function signature:</term> If
                     the declared type of the streaming parameter permits more than one node,
                     the function is not <termref def="dt-guaranteed-streamable"/>.</p><p><term>Rules for the function body:</term> 
                     For the function to be <termref def="dt-guaranteed-streamable"/>, 
                     the <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted posture</termref> of
                     the function body with respect to the declared return type must be <termref def="dt-crawling"/>, and the 
                     <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted sweep</termref> of the function body 
                     with respect to the declared return type must be <termref def="dt-motionless"/> or <termref def="dt-consuming"/>.</p><p><term>Rules for references to the streaming
                        parameter:</term> Such a variable reference is
                        <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p><p><term>Rules for function calls:</term> The rules are as follows, in order:</p><olist><item><p>Let <var>T0</var> be the <termref def="dt-utype"/> corresponding to the
                           declared type of the <termref def="dt-streaming-parameter"/> in the
                           function signature (defaulting to <var>U{*}</var>).</p></item><item><p>Let <var>P0</var> and <var>S0</var> be the <termref def="dt-type-adjusted-posture-and-sweep"/> of the first argument
                           expression, based on type <var>T0</var>.</p></item><item><p>If <var>P0</var> is not <termref def="dt-striding"/> or <termref def="dt-grounded"/>, the function call is <termref def="dt-roaming"/>
                           and <termref def="dt-free-ranging"/>.</p></item><item><p>Consider a construct <var>C</var> whose operands are the argument
                           expressions other than the first argument, with <termref def="dt-type-determined-usage">type-determined operand usage</termref>
                           based on the declared type of the corresponding parameter in the function
                           signature. Let <var>P1</var> and <var>S1</var> be the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of <var>C</var>,
                           assessed using the <termref def="dt-general-streamability-rules"/></p><note><p>If there is only one argument, then <var>P1</var> is <termref def="dt-grounded"/> and <var>S1</var> is <termref def="dt-motionless"/>.</p></note></item><item><p>If <var>P1</var> is not <termref def="dt-grounded"/>, the function call
                           is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If <var>S0</var> and <var>S1</var> are both <termref def="dt-consuming"/>, or if either is <termref def="dt-free-ranging"/>, the function call
                           is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If <var>P0</var> is <termref def="dt-grounded"/>, then the <termref def="dt-posture"/> of the function call is <termref def="dt-grounded"/>, and the <termref def="dt-sweep"/> of the function call is the wider
                           of <var>S0</var> and <var>S1</var>.</p></item><item><p>Otherwise, the <termref def="dt-posture"/> of the function call is
                              <termref def="dt-crawling"/>, and the <termref def="dt-sweep"/> of the
                           function call is as follows:</p><olist><item><p>If the intersection of <var>T0</var> with
                                       <var>U{document-node(), element()}</var> is empty (that is,
                                    the declared type of the first argument does not permit document
                                    or element nodes) then <var>S0</var>.</p></item><item><p>Let <var>A</var> be the <termref def="dt-static-type"/> of the
                                    expression supplied as the first argument. If the intersection
                                    of <var>A</var> with <var>U{document-node(), element()}</var> is
                                    empty (that is, the inferred type of the expression supplied as
                                    the first argument does not permit document or element nodes)
                                    then <var>S0</var>.</p></item><item><p>Otherwise, <termref def="dt-consuming"/>.</p></item></olist></item></olist><example><head>A deep-descent stylesheet function</head><p>The following function is declared as deep-descent, and the function body
                        meets the rules for this category because it selects descendants of the
                        supplied input node.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:all-comments" as="comment()*" 
                                    streamability="deep-descent"&gt;
  &lt;xsl:param name="input" as="element()"/&gt;
  &lt;xsl:sequence select="$input//comment()"/&gt;
&lt;/xsl:function&gt;</eg><p>The effect of the rules is that a call to this function is guaranteed
                        streamable in the typical case where the node supplied as the value of
                        the <code nobreak="false">$input</code> argument is <termref def="dt-striding"/> and
                           <termref def="dt-consuming"/>.</p></example></div3><div3 id="category-ascent"><head>Streamability Category: ascent</head><p><term>Informal description:</term> Functions in this category typically return
                     ancestors of the nodes supplied in the first argument. </p><p><term>Rules for the function signature:</term> If
                     the declared type of the streaming parameter permits more than one node,
                     the function is not <termref def="dt-guaranteed-streamable"/>.</p><p><term>Rules for the function body:</term> 
                     For the function to be <termref def="dt-guaranteed-streamable"/>, 
                     the <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted posture</termref> of
                     the function body with respect to the declared return type must be either 
                     <termref def="dt-climbing"/> or <termref def="dt-grounded"/>, and the 
                     <termref def="dt-type-adjusted-posture-and-sweep">type-adjusted sweep</termref> of the function body 
                     with respect to the declared return type must be <termref def="dt-motionless"/>.</p><p><term>Rules for references to the streaming
                        parameter:</term> Such a variable reference is
                        <termref def="dt-climbing"/> and <termref def="dt-motionless"/>.</p><p><term>Rules for function calls:</term> The <termref def="dt-posture"/> and
                        <termref def="dt-sweep"/> of a call to a function in this category are
                     determined as follows:</p><olist><item><p>Let <var>P0</var> and <var>S0</var> be the <termref def="dt-posture"/>
                           and <termref def="dt-sweep"/> obtained by assessing the function call
                           using the <termref def="dt-general-streamability-rules"/>, where the
                           operands are the arguments to the function call, with an <termref def="dt-operand-usage"/> 
                           for the first argument of <phrase diff="chg" at="2022-01-01"><termref def="dt-transmission"/></phrase>, 
                           and an <termref def="dt-operand-usage"/> for
                           arguments after the first being the <termref def="dt-type-determined-usage"/> based on the declared type of the
                           corresponding <xtermref spec="XT40" ref="dt-function-parameter"/>. 
                           <!--<phrase diff="add" at="2022-01-01">[XSLT 3.0 Erratum E31, bug 30289]</phrase>--></p></item><item><p>If <var>P0</var> is <termref def="dt-roaming"/> or <var>S0</var> is
                              <termref def="dt-free-ranging"/>, then the function call is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If <var>S0</var> is not <termref def="dt-motionless"/>, then the function
                           call is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If <var>P0</var> is <termref def="dt-roaming"/>, then the function call
                           is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If <var>P0</var> is <termref def="dt-grounded"/>, then the function call
                           is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item><item diff="add" at="2022-01-01"><p>If the declared return type of the function does not permit nodes, then the function call
                           is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.<!-- [XSLT 3.0 Erratum E31, bug 30289].--></p></item><item><p>Otherwise, the function call is <termref def="dt-climbing"/> and <termref def="dt-motionless"/>.</p></item></olist><example><head>An ascending stylesheet function</head><p>The following function is declared with category <code nobreak="false">ascent</code>, and
                        the function body meets the rules for this category because it selects
                        ancestors of the supplied node.</p><eg role="xslt-declaration xmlns:f='f'" xml:space="preserve">
&lt;xsl:function name="f:containing-section" as="element(section)" 
                                          streamability="ascent"&gt;
  &lt;xsl:param name="input" as="element(para)*"/&gt;
  &lt;xsl:sequence select="$input/ancestor::section[last()]"/&gt;
&lt;/xsl:function&gt;</eg><p>The effect of the rules is that a call to this function is guaranteed
                        streamable provided that the node supplied as the value of the
                           <code nobreak="false">input</code> argument is not <termref def="dt-roaming"/> or
                           <termref def="dt-free-ranging"/>. There are no other constraints on the
                        node supplied in the input sequence.</p></example></div3></div2></div1><div1 id="streamability-of-attribute-sets"><head>Streamable Attribute Sets</head><p>An <xtermref spec="XT40" ref="dt-attribute-set">attribute set</xtermref> may be designated as
                  streamable by including the attribute <code nobreak="false">streamable="yes"</code> on each
                     <elcode>xsl:attribute-set</elcode> declaration making up the attribute set. If
                  any <elcode>xsl:attribute-set</elcode> declaration for an attribute set has the
                  attribute <code nobreak="false">streamable="yes"</code>, then every
                     <elcode>xsl:attribute-set</elcode> declaration for that attribute set
                     <rfc2119>must</rfc2119> have the attribute <code nobreak="false">streamable="yes"</code>.</p><p>An <xtermref spec="XT40" ref="dt-attribute-set">attribute set</xtermref> is
                     <termref def="dt-guaranteed-streamable"/> if all the following conditions are
                  satisfied:</p><olist><item><p>Every <elcode>xsl:attribute-set</elcode>
                        declaration for the attribute set has the attribute
                           <code nobreak="false">streamable="yes"</code>.</p></item><item><p>Every <elcode>xsl:attribute-set</elcode> declaration for the attribute set
                        is <termref def="dt-grounded"/> and <termref def="dt-motionless"/> according to the analysis in <specref ref="classifying-attribute-sets"/>.</p></item></olist><p>Specifying <code nobreak="false">streamable="yes"</code> on an
                     <elcode>xsl:attribute-set</elcode> element declares an intent that the
                  attribute set should be streamable, either
                     because it is <termref def="dt-guaranteed-streamable"/>, or because it takes
                     advantage of streamability extensions offered by a particular
                     processor. The consequences of declaring the attribute set to be
                  streamable when it is not in fact guaranteed streamable depend on the conformance
                  level of the processor, and are explained in <specref ref="streamability-guarantees"/>.</p><p><error spec="XT" type="static" class="SE" code="0730"><p>If an <elcode>xsl:attribute</elcode> set element specifies
                           <code nobreak="false">streamable="yes"</code> then every attribute set referenced in its
                           <code nobreak="false">use-attribute-sets</code> attribute (if present) must also specify
                           <code nobreak="false">streamable="yes"</code>.</p></error></p><note><p>It is common for attribute sets to create attributes with constant values, and
                     such attribute sets will always be grounded and motionless and therefore streamable.
                     Although such cases are fairly simple for a processor to detect, references to
                     attribute sets are not guaranteed streamable unless the attribute set is
                     declared with the attribute <code nobreak="false">streamable="yes"</code>, which should
                     therefore be used if interoperable streaming is required.</p></note><div2 id="classifying-attribute-sets"><head>Classifying Attribute Sets</head><p>The <termref def="dt-posture"/> of an <xtermref spec="XT40" ref="dt-attribute-set"/>
               is always <termref def="dt-grounded"/> (its result can never return streamed nodes).</p><p>The <termref def="dt-sweep"/> of an <xtermref spec="XT40" ref="dt-attribute-set"/>
                  is <termref def="dt-motionless"/> if all the following conditions hold:</p><olist><item><p>Every <elcode>xsl:attribute</elcode> instruction within the declarations comprising the attribute set
                     is <termref def="dt-motionless"/> when assessed as described in <specref ref="streamability-of-attribute-sets"/>,
                  using a <termref def="dt-context-posture"/> of <termref def="dt-striding"/>.</p></item><item><p>Every attribute set referenced in the <code nobreak="false">use-attribute-sets</code> attribute of an <elcode>xsl:attribute-set</elcode>
                  declaration of the attribute set has the attribute <code nobreak="false">streamable="yes"</code>.</p></item><item><p/></item></olist><p>If the <termref def="dt-sweep"/> of an <xtermref spec="XT40" ref="dt-attribute-set"/>
                  is not <termref def="dt-motionless"/> then it is <termref def="dt-free-ranging"/>.</p><note><p>Attribute sets will always be <termref def="dt-grounded"/>,
                     because they return newly constructed attribute nodes.</p><p>Attribute sets will very often be <termref def="dt-motionless"/>, but if they
                     access the context item, they may be <termref def="dt-free-ranging"/>. Although some attribute sets could theoretically be
                  classified as <termref def="dt-consuming"/>, this option has been excluded because
                  it is unlikely to be useful; given the requirement to create attributes whose values
                  are obtained by reading a streamed input document, use of a streamable <xtermref spec="XT40" ref="dt-template-rule"/>
                  is a more versatile approach.</p><p>Because attribute sets can be overridden in another <xtermref spec="XT40" ref="dt-package"/>, 
                    the streamability of a construct such as an
                        <elcode>xsl:element</elcode> instruction containing a
                        <code nobreak="false">use-attribute-sets</code> attribute is based on the declared
                     streamability of the named attribute sets, as defined by the
                        <code nobreak="false">streamable</code> attribute of the <elcode>xsl:attribute-set</elcode>
                     element. If <code nobreak="false">streamable="yes"</code> is specified, then there is a
                     requirement that any overriding attribute set should also specify
                        <code nobreak="false">streamable="yes"</code>, and a streaming processor is required to
                     check that an attribute set containing such a declaration does in fact satisfy
                     the streamability rules.</p></note></div2></div1><div1 id="streamable-merging"><head>Streamable Merging</head><p>Any input to a merging operation, provided it is selected
               by means of the <elcode>xsl:merge-source</elcode> element with a
                  <code nobreak="false">for-each-source</code> attribute, may be designated as streamable by
               including the attribute <code nobreak="false">streamable="yes"</code> on the
                  <elcode>xsl:merge-source</elcode> element. </p><p>When <code nobreak="false">streamable="yes"</code> is specified on an
                  <elcode>xsl:merge-source</elcode> element, then (whether or not streamed
               processing is actually used, and whether or not the processor supports streaming) the
               expression appearing in the <code nobreak="false">select</code> attribute is implicitly used as the
               argument of a call on the <function>snapshot</function> function, which means that
               merge keys for each selected node are computed with reference to this snapshot, and
               the <function>current-merge-group</function> function, when used within the
                  <elcode>xsl:merge-action</elcode> sequence constructor, delivers snapshots of the
               selected nodes.</p><note><p>There are therefore no constraints on the navigation
                  that may be performed in computing the merge key, or in the course of evaluating
                  the <elcode>xsl:merge-action</elcode> body. An attempt to navigate outside the
                  portion of the source document delivered by the <function>snapshot</function>
                  function will typically not cause an error, but will return empty results.</p><p>There is no
                  rule to prevent the <code nobreak="false">select</code> expression returning atomic items, or grounded nodes from a
                  different source document, or newly constructed nodes, but they are still
                  processed using the <function>snapshot</function> function.</p><p>Because the <function>snapshot</function> copies
                  accumulator values as described in <xspecref spec="XT40" ref="copying-accumulators"/>, the
                  functions <function>accumulator-before</function> and
                     <function>accumulator-after</function> may be used to gain access to
                  information that is not directly available in the nodes that are present within
                  each snapshot (for example, information in a header section of the merge input
                  document).</p></note><p>An <elcode>xsl:merge-source</elcode> element is <termref def="dt-guaranteed-streamable"/> if it satisfies all the following conditions:</p><olist><item><p>The <elcode>xsl:merge-source</elcode> element has the 
                     attribute value <code nobreak="false">streamable="yes"</code>;</p></item><item><p>The <code nobreak="false">for-each-source</code> attribute is
                     present on that <elcode>xsl:merge-source</elcode> element;</p></item><item><p>The expression in the <code nobreak="false">select</code> attribute of that
                        <elcode>xsl:merge-source</elcode> element, assessed with a
                  <termref def="dt-context-posture"/> of <termref def="dt-striding"/>
                  and a <termref def="dt-context-item-type"/> of <var>U{document-node()}</var>,
                  has <termref def="dt-striding"/> or <termref def="dt-grounded"/> <termref def="dt-posture"/>
                     and <termref def="dt-motionless"/> or <termref def="dt-consuming"/> <termref def="dt-sweep"/>;
                  </p></item><item><p>The <code nobreak="false">sort-before-merge</code> attribute of that
                        <elcode>xsl:merge-source</elcode> element is either absent or takes its
                     default value of <code nobreak="false">no</code>.</p></item></olist><p>Specifying <code nobreak="false">streamable="yes"</code> on an
               <elcode>xsl:merge-source</elcode> element declares an intent that the
                  <elcode>xsl:merge</elcode> instruction should be streamable with respect to that particular source, either because it is <termref def="dt-guaranteed-streamable"/>, or because it takes advantage of
                  streamability extensions offered by a particular processor. The
               consequences of declaring the instruction to be streamable when it is not in fact
               guaranteed streamable depend on the conformance level of the processor, and are
               explained in <specref ref="streamability-guarantees"/>.</p><example><head>Streamed Merging</head><p>The following example merges two log files, processing each of them using
                  streaming.</p><eg role="xslt-fragment" xml:space="preserve">
&lt;events&gt;
   &lt;xsl:merge&gt;
      &lt;xsl:merge-source for-each-source="'log-file-1.xml'" 
                        select="/events/event" 
                        streamable="yes"&gt;
         &lt;xsl:merge-key select="@timestamp"/&gt;
      &lt;/xsl:merge-source&gt;
      &lt;xsl:merge-source for-each-source="'log-files-2.xml'" 
                        select="/log/day/record" 
                        streamable="yes"&gt;
         &lt;xsl:merge-key select="dateTime(../@date, time)"/&gt;
      &lt;/xsl:merge-source&gt;
      &lt;xsl:merge-action&gt;
         &lt;events time="{current-merge-key()}"&gt;
            &lt;xsl:copy-of select="current-merge-group()"/&gt;
         &lt;/events&gt;   
      &lt;/xsl:merge-action&gt;
   &lt;/xsl:merge&gt;
&lt;/events&gt;</eg></example><p>Note that the merge key for the second merge source includes data from a child
               element of the selected element and also from an attribute of the parent element.
               This works because the merge key is evaluated on the result of implicitly applying
               the <function>snapshot</function> function.</p><example><head>Merging XML and non-XML Data</head><p>The following example merges two log files, one in text format and one in XML format.</p><eg role="xslt-instruction" xml:space="preserve">
&lt;events&gt;
   &lt;xsl:merge&gt;
      &lt;xsl:merge-source name="fax" 
                        select="unparsed-text-lines('fax-log.txt')"&gt;
         &lt;xsl:merge-key select="xs:dateTime(substring-before(., ' '))"/&gt;
      &lt;/xsl:merge-source&gt;
      &lt;xsl:merge-source name="mail"
                        for-each-source="'mail-log.xml'" 
                        select="/log/day/message" 
                        streamable="yes"&gt;
         &lt;xsl:merge-key select="dateTime(../@date, @time)"/&gt;
      &lt;/xsl:merge-source&gt;
      &lt;xsl:merge-action&gt;
         &lt;messages at="{current-merge-key()}"&gt;
            &lt;xsl:where-populated&gt;
               &lt;fax&gt;
                  &lt;xsl:for-each select="current-merge-group('fax')"&gt;
                     &lt;message xsl:expand-text="true"&gt;{
                        substring-after(., ' ')
                     }&lt;/message&gt;
                  &lt;/xsl:for-each&gt;   
               &lt;/fax&gt;
               &lt;mail&gt;
                  &lt;xsl:sequence select="current-merge-group('mail')/*"/&gt;
               &lt;/mail&gt;
            &lt;/xsl:where-populated&gt;   
         &lt;/messages&gt;   
      &lt;/xsl:merge-action&gt;
   &lt;/xsl:merge&gt;
&lt;/events&gt;</eg></example></div1><div1 id="streamability-of-accumulators"><head>Streamable Accumulators</head><p>Accumulators were introduced to the XSLT language specifically with the needs of
               streaming applications in mind. They allow information from a streamed source document
               (for example, the contents of a header element) to be retained for use when subsequent
               elements in the document are processed.</p><p>The <code nobreak="false">capture</code> attribute introduced in XSLT 4.0 
                 (see <xspecref spec="XT40" ref="capturing-accumulators"/>)
               further increases the power of this approach.</p><p>An accumulator is <termref def="dt-guaranteed-streamable"/> if
                  it satisfies all the following
                  conditions:</p><olist><item><p>The <elcode>xsl:accumulator</elcode> declaration has the attribute
                           <code nobreak="false">streamable="yes"</code> (that is, it is <termref def="dt-declared-streamable"/>).</p></item><item><p>In every contained <elcode>xsl:accumulator-rule</elcode>, the 
                       <xtermref spec="XT40" ref="dt-pattern">pattern</xtermref> in the <code nobreak="false">match</code> attribute is
                        a <termref def="dt-motionless"/> pattern (see <specref ref="classifying-patterns"/>).</p></item><item><p>The <xtermref spec="XT40" ref="dt-expression">expression</xtermref> in the
                           <code nobreak="false">initial-value</code> attribute is <termref def="dt-grounded"/> and
                           <termref def="dt-motionless"/>.</p></item><item><p><phrase diff="add" at="issue211">In an <elcode>xsl:accumulator-rule</elcode> with 
                        <code nobreak="false">phase="start"</code> (the default value),</phrase>
                        the <termref def="dt-type-adjusted-posture-and-sweep"/> of
                        the <xtermref spec="XT40" ref="dt-expression">expression</xtermref> in the <code nobreak="false">select</code> attribute or the contained
                           <xtermref spec="XT40" ref="dt-sequence-constructor"/>, with respect to the declared type of the accumulator,
                           is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item><item diff="add" at="issue211"><p>In an <elcode>xsl:accumulator-rule</elcode> with 
                        <code nobreak="false">phase="end"</code>, one of the
                        following conditions holds:</p><olist><item><p>The rule has <code nobreak="false">capture="no"</code> (the default value),
                           and the <termref def="dt-type-adjusted-posture-and-sweep"/> of
                           the <xtermref spec="XT40" ref="dt-expression">expression</xtermref> in the <code nobreak="false">select</code> attribute or the contained
                           <xtermref spec="XT40" ref="dt-sequence-constructor"/>, with respect to the declared type of the accumulator,
                           is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item><item><p diff="chg" at="issue731">The rule has <code nobreak="false">capture="yes"</code>.</p></item></olist></item></olist><p>Specifying <code nobreak="false">streamable="yes"</code> on an
                     <elcode>xsl:accumulator</elcode> element declares an intent that the
                  accumulator should be streamable, either
                     because it is <termref def="dt-guaranteed-streamable"/>, or because it takes
                     advantage of streamability extensions offered by a particular
                     processor. The consequences of declaring the accumulator to be
                  streamable when it is not in fact guaranteed streamable depend on the conformance
                  level of the processor, and are explained in <specref ref="streamability-guarantees"/>.</p><p>When an accumulator is declared to be streamable, the
                  stylesheet author must ensure that the accumulator function
                     <function>accumulator-after</function> is only called at appropriate points in
                  the processing, as explained in <specref ref="streamability-fn-accumulator-after"/>.</p><p>For constructs that use accumulators to be
                        <termref def="dt-guaranteed-streamable"/>:</p><ulist><item><p>The <function>accumulator-before</function> function for a streamed node can
                        be called at any time the node is available (it behaves like other
                        properties of the node such as <xfunction>name</xfunction> or
                           <xfunction>base-uri</xfunction>).</p></item><item><p>The <function>accumulator-after</function> function, however, is restricted
                            to appear after any instruction that reads the descendants
                        of the node in question. The constraints are expressed as static rules: see
                           <specref ref="streamability-fn-accumulator-after"/> for more details.</p></item></ulist></div1><div1 id="streamability-of-constructs"><head>Streamability of Specific Constructs</head><div2 id="maps-streaming"><head>Maps and Streaming</head><p>Maps have many uses, but their introduction to XSLT 3.0 was strongly motivated by
               streaming use cases. In essence, when a source document is processed in streaming
               mode, data that is encountered in the course of processing may need to be retained in
               variables for subsequent use, because the nodes cannot be revisited. This creates a
               need for a flexible data structure to accommodate such temporary data, and maps were
               designed to fulfil this need.</p><p>The entries in a map are not allowed to contain references to 
               <termref def="dt-streamed-node">streamed nodes</termref>. This is achieved by ensuring that for all constructs
            that supply content to be included in a map (for example the third argument of <function>map:put</function>, and
               the <code nobreak="false">select</code> attribute of <elcode>xsl:map-entry</elcode>),
            the relevant operand is defined to have operand usage <termref def="dt-navigation"/>. Because maps cannot
               contain references to streamed nodes, they are effectively <termref def="dt-grounded"/>, and can therefore
               be used freely in contexts (such as parameters to functions or templates) where only grounded operands
               are permitted.</p><p>The <elcode>xsl:map</elcode> instruction, and the XPath <code nobreak="false">MapConstructor</code>
               construct, are exceptions to the general rule that during streaming, only one
               downward selection (one consuming subexpression) is permitted. They share this
               characteristic with <elcode>xsl:fork</elcode>. As with <elcode>xsl:fork</elcode>, a
               streaming processor is expected to be able to construct the map during a single pass
               of the streamed input document, which may require multiple expressions to be
               evaluated in parallel.</p><p>In the case of the <elcode>xsl:map</elcode> instruction, this exemption applies only in the
               case where the instruction consists exclusively of <elcode>xsl:map-entry</elcode>
               (and <elcode>xsl:fallback</elcode>) children, and not in more complex cases where the
               map entries are constructed dynamically (for example using a control flow implemented
               using <elcode>xsl:choose</elcode>, <elcode>xsl:for-each</elcode>, or
                  <elcode>xsl:call-template</elcode>). Such cases may, of course, be streamable
               if they only have a single consuming subexpression.</p><p>For example, the following XPath expression is streamable, despite making two
               downward selections:</p><eg role="non-xml" xml:space="preserve">
let $m := { 'price': xs:decimal(price), 'discount': xs:decimal(discount) } 
return ($m?price - $m?discount)</eg><p>Analysis:</p><olist><item><p>Because the <code nobreak="false">return</code> clause is motionless, the <termref def="dt-sweep"/> of the <code nobreak="false">let</code> expression is the sweep of the map
                     expression (the expression in curly brackets).</p></item><item><p>The sweep of a map expression is the maximum sweep of its key/value pairs.</p></item><item><p>For both key/value pairs, the key is <termref def="dt-motionless"/> and the
                     value is <termref def="dt-consuming"/>.</p></item><item><p>The expression carefully atomizes both values, because
                     retaining references to streamed nodes in a map is not permitted.</p></item><item><p>Therefore the map expression, and hence the expression as a whole, is <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></item></olist><p>The streamability of the <elcode>xsl:record</elcode> instruction is determined
                 by analysing the streamability of the equivalent <elcode>xsl:map</elcode> instruction 
                 as described in the definition of <elcode>xsl:record</elcode> above.</p><p>See also: <specref ref="streamability-of-map-constructors"/>, <specref ref="streamability-xsl-map"/>,
                <specref ref="streamability-xsl-map-entry"/>, <specref ref="streamability-xsl-record"/></p></div2><div2 id="keys-and-streaming"><head>Keys and Streaming</head><p>Keys are not applicable to streamed documents.</p><p>This is ensured by the rules for the streamability of the <function>key</function> function 
               (see <specref ref="classifying-built-in-functions"/>). These rules make the <termref def="dt-operand-usage"/> of the
               third argument <termref def="dt-navigation"/>, which has the consequence that when the <function>key</function> function
            is applied to a streamed input document, the call is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>, which effectively makes
            the containing construct non-streamable.</p></div2><div2 id="grounded-consuming-constructs"><head>Grounded Consuming Constructs</head><p>A construct is grounded if the items it delivers do not include nodes from a 
               streamed document; it is consuming if evaluation of the construct reads nodes 
               from a streamed input in a way that requires advancing the current position in the input.
            </p><p>Grounded consuming constructs play an important role in streaming, and this 
               section discusses some of their characteristics.
            </p><p>Examples of grounded consuming constructs (assuming the context item is a streamed node) include:
            </p><ulist><item><p><code nobreak="false">sum(.//transaction/@value)</code></p></item><item><p><code nobreak="false">copy-of(./account/history/event)</code></p></item><item><p><code nobreak="false">distinct-values(./account/@account-nr)</code></p></item><item><p><code nobreak="false">&lt;xsl:for-each select="transaction"&gt;&lt;t&gt;&lt;xsl:value-of select="@value"/&gt;&lt;/t&gt;&lt;/xsl:for-each&gt;</code></p></item></ulist><p>XSLT 3.0 provides the two functions <function>copy-of</function> and <code nobreak="false">snapshot</code>
               with the explicit purpose of creating a sequence of grounded nodes, that can be processed
               one-by-one without the usual restrictions that apply to streamed processing, such as the
               rule permitting at most one downward selection. The processing style that exploits these
               functions is often called “windowed streaming”.</p><p>In general the result of a grounded consuming construct is a sequence. Depending on how 
               this sequence is used, it may or may not be necessary for the processor to allocate sufficient 
               memory to hold the entire sequence. The streamability rules in this specification place few 
               constraints on how a grounded sequence is used. This is deliberate, because it gives users 
               control: by creating a grounded sequence (for example, by use of the copy-of function) 
               stylesheet authors create the possibility to process data in arbitrary ways (for example, 
               by sorting the sequence), and accept the possibility that this may consume memory.
            </p><p>Pipelined evaluation of a sequence is analogous to streamed processing of a source document. 
               Pipelined evaluation occurs when the items in a sequence can be processed one-by-one, without 
               materializing the entire sequence in memory. Pipelining is a common optimization technique in 
               all functional programming languages. Operations for which pipelined evaluation is commonly 
               performed include filtering (<code nobreak="false">$transactions[@value gt 1000]</code>), mapping 
               (<code nobreak="false">$transactions!(@value - @processing-fee)</code>), and aggregation 
               (<code nobreak="false">sum($transactions)</code>). Operations that cannot be pipelined (because, 
               for example, the first item in the result sequence cannot be computed without knowing 
               the last item in the input sequence) include those that change the order of items 
               (<code nobreak="false">reverse()</code>, <code nobreak="false">sort()</code>). Other operations such as <code nobreak="false">distinct-values()</code> 
               allow the input to be processed one item at a time, but require memory that potentially 
               increases as the sequence length increases. Saving a grounded sequence in a variable is 
               also likely in many cases to require allocation of memory to hold the entire sequence.
            </p><p>When the input to an operation is a grounded consuming sequence (more accurately, 
               a sequence resulting from the evaluation of a grounded consuming construct), this specification 
               does not attempt to dictate whether the operation is pipelined or not. The goal of interoperable 
               streaming in finite memory can therefore only be achieved if stylesheet authors take care to avoid 
               constructing grounded sequences that occupy large amounts of memory. In practice, however, users 
               can expect that many grounded consuming constructs will be pipelined where the semantics permit this.
            </p><note><p>Some processors may recognize an opportunity for pipelining only if the expression
            is written in a particular way. For example the constructs <code nobreak="false">copy-of(/a/b/c)</code> and
            <code nobreak="false">/a/b/c/copy-of(.)</code> are to all intents and purposes equivalent, but some processors
            might recognize the second form more easily as suitable for pipelining.</p><p>(There is one minor difference between these expressions: the order of nodes in <code nobreak="false">copy-of(/a/b/c)</code>
            is required to reflect the document order of the nodes in <code nobreak="false">/a/b/c</code>, while the result
            of <code nobreak="false">/a/b/c/copy-of(.)</code> can be in any order, in consequence of the rule that document order
            for nodes in different trees is implementation-dependent.)</p></note><p>The use of the <xfunction>last</xfunction> function requires particular care because of
               its effect on pipelining.  The streamability rules prevent the use of <code nobreak="false">last()</code> in 
               conjunction with an expression that returns streamed nodes (because it would require look-ahead 
               in the stream), but there is no similar constraint for grounded sequences. So for example it 
               is not permitted (in a context that requires streaming) to write
            </p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:for-each select="transaction"&gt;
  &lt;xsl:value-of select="position(), ' of ', last()"/&gt;
&lt;/xsl:for-each&gt;</eg><p>but it is quite permissible to write</p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:for-each select="transaction/copy-of()"&gt;
  &lt;xsl:value-of select="position(), ' of ', last()"/&gt;
&lt;/xsl:for-each&gt;</eg><p>because the call on <function>copy-of</function> makes the sequence grounded. This construct
               cannot be pipelined because computing the first item in the result sequence depends on knowing
               the length of the input sequence; in consequence, a processor might be obliged to buffer all
               the transactions (or their copies) in memory.
               In this simple example the impact of the call on <xfunction>last</xfunction> is easily detected 
               both by the human reader and by the XSLT processor, but there are other cases where the effect 
               is less obvious. For example if the stylesheet executes the instruction
            </p><eg role="xslt-instruction" xml:space="preserve">&lt;xsl:apply-templates select="transaction/copy-of(.)"/&gt;</eg><p>then the presence of a call on <xfunction>last</xfunction> in one of the template rules 
                  that gets invoked might not be easily spotted; yet the effect is exactly the same 
                  in preventing the result being computed by processing input items strictly one at 
                  a time. Avoiding such effects is entirely the responsibility of the stylesheet author.
               </p><p>By contrast, there is no intrinsic reason why use of the <xfunction>position</xfunction> should
            prevent pipelined processing: all it requires is for the processor to count how many items have been
            processed so far. Processors may also be able to handle the construct <code nobreak="false">position() = last()</code>
            without storing the entire sequence in memory; rather than actually evaluating the numeric values of
            <code nobreak="false">position()</code> and <code nobreak="false">last()</code>, this can be done by testing whether the context item
            is the last item in the sequence, which only requires a one-item lookahead.</p></div2><!--<div2 id="classifying-constructs">
            <head>Classifying Constructs</head>

            <p>This section defines the properties of every kind of <termref def="dt-construct"/>
               that may appear in a <xtermref spec="XT40" ref="dt-stylesheet"/>. It identifies the <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usage</termref>, and it gives the rules that define the
                  <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the construct. In
               cases where the <termref def="dt-general-streamability-rules"/> apply, there is still
               an entry for the construct in order to define its <termref def="dt-operand">operands</termref> and their usages, since this information is needed by the
               general rules.</p>


            <p>The following sections describe this categorization for each kind of construct:</p>

            <ulist>
               <item>
                  <p>Sequence constructors: see <specref ref="classifying-sequence-constructors"/></p>
               </item>
               <item>
                  <p>Instructions: see <specref ref="classifying-instructions"/></p>
               </item>
               <item>
                  <p>Stylesheet functions: see <specref ref="streamable-stylesheet-functions"/></p>
               </item>
               <item>
                  <p>Attribute sets: see <specref ref="classifying-attribute-sets"/></p>
               </item>
               <item>
                  <p>Value templates: see <specref ref="classifying-vts"/></p>
               </item>
               <item>
                  <p>Expressions: see <specref ref="classifying-expressions"/></p>
               </item>
               <item>
                  <p>Patterns: see <specref ref="classifying-patterns"/></p>
               </item>
               <item>
                  <p>Calls to built-in functions: see <specref ref="classifying-built-in-functions"/></p>
               </item>
            </ulist>


--><div2 id="classifying-sequence-constructors"><head>Classifying Sequence Constructors</head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep">sweep</termref> of a
                     <xtermref spec="XT40" ref="dt-sequence-constructor"/> are determined by the <termref def="dt-general-streamability-rules"/>.</p><p>The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are:</p><olist><item><p>The immediately contained
                           <xtermref spec="XT40" ref="dt-instruction">instructions</xtermref>
                        and <xtermref spec="XT40" ref="dt-literal-result-element">literal result elements</xtermref>,
                           including any <elcode>xsl:on-empty</elcode> or
                              <elcode>xsl:on-non-empty</elcode> instructions. The <termref def="dt-operand-usage"/> for these operands is <termref def="dt-transmission"/>.</p></item><item><p>Any <xtermref spec="XT40" ref="dt-text-value-template">text value templates</xtermref>
                        appearing in text nodes within the sequence constructor, if text value
                        templates are enabled. The <termref def="dt-operand-usage"/> for these
                        operands is <termref def="dt-absorption"/>.</p></item></olist><note><p>Some consequences of these rules are:</p><olist><item><p>An empty sequence constructor is <termref def="dt-motionless"/>, and its
                              <termref def="dt-posture"/> is <termref def="dt-grounded"/>.</p></item><item><p>A sequence constructor containing a single instruction has the same
                              <termref def="dt-sweep"/> and <termref def="dt-posture"/> as that
                           instruction. (This means that sequence constructors containing a single instruction
                           can usefully be dropped from the construct tree.)</p></item><item><p>Informally, a sequence constructor is not streamable if it contains more
                           than one instruction that moves the position of the input stream.</p></item><item><p><elcode>xsl:on-empty</elcode> or <elcode>xsl:on-non-empty</elcode>
                           instructions are not treated specially. For example, there is no attempt
                           to take into account that they are mutually exclusive: if one is
                           evaluated, the other will not be evaluated. In most use cases for these
                           instructions, they will be motionless, so the additional complexity of
                           doing more advanced analysis would rarely be justified.</p></item></olist></note></div2><div2 id="classifying-instructions"><head>Classifying Instructions</head><p>This section describes how <xtermref spec="XT40" ref="dt-instruction">instructions</xtermref>
                  are classified with respect to their streamability. The criteria are given first
                  for <xtermref spec="XT40" ref="dt-literal-result-element">literal result elements</xtermref> and
                     <xtermref spec="XT40" ref="dt-extension-instruction">extension instructions</xtermref>, then
                  for each XSLT instruction, listed alphabetically.</p><div3 id="streamability-literal-result-elements"><head>Streamability of Literal Result Elements</head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> 
                    of a <xtermref spec="XT40" ref="dt-literal-result-element"/> 
                    follow the <termref def="dt-general-streamability-rules"/>. 
                    The <termref def="dt-operand-role">operand roles</termref> 
                    and their <termref def="dt-operand-usage">usages</termref> are:</p><olist><item><p>The contained sequence constructor (usage <termref def="dt-absorption"/>)</p></item><item><p>Any expressions contained in 
                          <xtermref spec="XT40" ref="dt-attribute-value-template">attribute value templates</xtermref> 
                          among the literal result
                           element’s attributes (usage <termref def="dt-absorption"/>)</p></item><item><p>Any <xtermref spec="XT40" ref="dt-attribute-set">attribute sets</xtermref> named in the
                           <code nobreak="false">xsl:use-attribute-sets</code> attribute (usage irrelevant, but can be taken as <termref def="dt-inspection"/>).</p><note><p>In practice, a reference to an attribute set that is <termref def="dt-declared-streamable"/> does not
                        affect the analysis, while a reference to any other attribute set makes the literal result element
                        <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></note></item></olist></div3><div3 id="streamability-extension-instructions"><head>Streamability of extension instructions</head><p>For a processor that recognizes an <xtermref spec="XT40" ref="dt-extension-instruction"/>,
                     the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                     instruction are <termref def="dt-implementation-defined"/>.</p><imp-def-feature id="idf-ext-streamability">The <termref def="dt-posture"/> and
                        <termref def="dt-sweep"/> of <xtermref spec="XT40" ref="dt-extension-function">extension
                        functions</xtermref> (and references to extension functions) and 
                    <xtermref spec="XT40" ref="dt-extension-instruction">extension instructions</xtermref>
                    are <termref def="dt-implementation-defined"/>.</imp-def-feature><p>For a processor that does not recognize an <xtermref spec="XT40" ref="dt-extension-instruction"/>, the <termref def="dt-posture"/> and
                        <termref def="dt-sweep"/> of the instruction are determined by applying the
                        <termref def="dt-general-streamability-rules"/>. 
                    The <termref def="dt-operand-role">operand roles</termref> and 
                    their <termref def="dt-operand-usage">usages</termref> are:</p><olist><item><p>The <xtermref spec="XT40" ref="dt-sequence-constructor">sequence
                              constructors</xtermref> contained in any <elcode>xsl:fallback</elcode>
                           children (usage <termref def="dt-transmission"/>)</p></item></olist><p>Instructions in the XSLT namespace that are present under the provisions for
                        <xtermref spec="XT40" ref="dt-forwards-compatible-behavior"/> are treated in the same way
                     as unrecognized extension instructions.</p><note><p>These rules mean that if there is no <elcode>xsl:fallback</elcode> child
                        instruction, the containing construct will be classified as streamable.
                        However, any attempt to execute the instruction will lead to a dynamic
                        error, so in fact, neither streamed nor unstreamed evaluation is
                        possible.</p></note></div3><div3 id="streamability-xsl-analyze-string"><head>Streamability of <elcode>xsl:analyze-string</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:analyze-string</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are:</p><olist><item><p>the <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>);</p></item><item><p>the <code nobreak="false">regex</code> attribute value template (usage <termref def="dt-absorption"/>);</p></item><item><p>the sequence constructors contained in the
                              <elcode>xsl:matching-substring</elcode> and
                              <elcode>xsl:non-matching-substring</elcode> elements. These have usage
                              <termref def="dt-navigation"/>, because they can be evaluated more
                           than once. The <termref def="dt-context-posture"/> for the two sequence
                           constructors is <termref def="dt-grounded"/>, reflecting the fact that
                           their context item type is <code nobreak="false">xs:string</code>.</p></item></olist><note><p>In practice, the <termref def="dt-sweep"/> of the
                        instruction will usually be the same as the sweep of the <code nobreak="false">select</code>
                        expression, and its <termref def="dt-posture"/> will be <termref def="dt-grounded"/>. Exceptions occur for example if the
                           <code nobreak="false">regex</code> attribute is not <termref def="dt-motionless"/>, or if
                        the contained sequence constructors refer to a grouping variable bound in a
                        contained <elcode>xsl:for-each-group</elcode> instruction.</p></note></div3><div3 id="streamability-xsl-apply-imports"><head>Streamability of <elcode>xsl:apply-imports</elcode></head><p>The rules in this section apply also to <elcode>xsl:next-match</elcode>.</p><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of these two
                     instructions follow the <termref def="dt-general-streamability-rules"/>. The
                        <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are:</p><olist><item><p>An implicit operand: a context item expression (<code nobreak="false">.</code>), with
                           usage <termref def="dt-absorption"/>;</p></item><item><p>The <code nobreak="false">select</code> attribute or contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> of each
                              <elcode>xsl:with-param</elcode> child element, with <termref def="dt-type-determined-usage"/> based on the type declared in the
                              <code nobreak="false">xsl:with-param/@as</code> attribute, or <code nobreak="false">item()*</code> if
                           absent.</p></item></olist><note><p>The instruction will normally be <termref def="dt-grounded"/> and <termref def="dt-consuming"/>, provided that nodes in a streamed document are not
                        passed as parameters to the called template rule.</p></note></div3><div3 id="streamability-xsl-apply-templates"><head>Streamability of <elcode>xsl:apply-templates</elcode></head><p>If there is no <code nobreak="false">select</code> attribute, the following
                     analysis assumes the presence of an implicit operand
                        <code nobreak="false">select="child::node()"</code>.</p><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                        <elcode>xsl:apply-templates</elcode> instruction are the first of the
                     following that apply:</p><olist><item><p>If the <code nobreak="false">select</code> expression is <termref def="dt-grounded"/>,
                           then the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                              <elcode>xsl:apply-templates</elcode> instruction follow the <termref def="dt-general-streamability-rules"/>, with the <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (the <termref def="dt-operand-usage"/> is irrelevant, but can be taken as
                                    <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> expressions and contained sequence
                                 constructors of any child <elcode>xsl:with-param</elcode> elements
                                 (usage <termref def="dt-type-determined-usage">type-determined</termref>, based on the type in the
                                    <code nobreak="false">xsl:with-param/@as</code> attribute, defaulting to
                                    <code nobreak="false">item()*</code>)</p></item><item><p>Any attribute value templates appearing in attributes of a child
                                    <elcode>xsl:sort</elcode> instruction (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> expression or contained sequence
                                 constructor of any <elcode>xsl:sort</elcode> children, assessed
                                 with a <termref def="dt-context-posture"/> of <termref def="dt-grounded"/> (usage <termref def="dt-absorption"/>).</p></item></olist><p>For example, <code nobreak="false">&lt;xsl:apply-templates
                              select="copy-of(.)"/&gt;</code> is <termref def="dt-grounded"/> and
                              <termref def="dt-consuming"/>.</p></item><item><p>If there is an <elcode>xsl:sort</elcode> child element, then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If the implicit or explicit <code nobreak="false">mode</code> attribute identifies a
                              <xtermref spec="XT40" ref="dt-mode">mode</xtermref> that is not declared with
                              <code nobreak="false">streamable="yes"</code>, then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>. </p><note><p>When <code nobreak="false">mode="#current"</code> is specified, this is treated as
                              equivalent to specifying a streamable mode; although it is not known
                              statically what the mode will be, it is always the case that if the
                              template is invoked with a streamed node as the context item, then the
                              current mode must be a streamable mode.</p></note></item><item><p>If the <code nobreak="false">select</code> expression is <termref def="dt-climbing"/> or
                              <termref def="dt-crawling"/>, then <termref def="dt-roaming"/> and
                              <termref def="dt-free-ranging"/></p></item><item><p>Otherwise, the <termref def="dt-posture"/> and <termref def="dt-sweep"/>
                           of the <elcode>xsl:apply-templates</elcode> instruction follow the
                              <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The (explicit or implicit) <code nobreak="false">select</code> expression, with
                                 usage <termref def="dt-absorption"/>; </p></item><item><p>The <code nobreak="false">select</code> attribute or contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> of each
                                    <elcode>xsl:with-param</elcode> child element, with <termref def="dt-type-determined-usage"/> based on the type declared in
                                 the <code nobreak="false">xsl:with-param/@as</code> attribute, or
                                    <code nobreak="false">item()*</code> if absent.</p></item></olist></item></olist></div3><div3 id="streamability-xsl-assert"><head>Streamability of <elcode>xsl:assert</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:assert</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">test</code> expression (usage <termref def="dt-inspection"/>)</p></item><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">error-code</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-attribute"><head>Streamability of <elcode>xsl:attribute</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:attribute</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">name</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">namespace</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">separator</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-break"><head>Streamability of <elcode>xsl:break</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:break</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-transmission"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-transmission"/>).</p></item></olist></div3><div3 id="streamability-xsl-call-template"><head>Streamability of <elcode>xsl:call-template</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:call-template</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>Unless the referenced template has a child
                              <elcode>xsl:context-item</elcode> element with the attribute
                              <code nobreak="false">use="prohibited"</code>, there is an implicit operand, a context
                           item expression (<code nobreak="false">.</code>): its <termref def="dt-operand-usage"/>
                           is the <termref def="dt-type-determined-usage"/> based on the type
                           declared in the <code nobreak="false">xsl:context-item/@as</code> attribute of the target
                           named template, defaulting to <code nobreak="false">item()*</code> if absent.</p></item><item><p>The <code nobreak="false">select</code> expression or sequence constructor content of any
                           contained <elcode>xsl:with-param</elcode> child element: its <termref def="dt-operand-usage"/> is the <termref def="dt-type-determined-usage"/> based on the type declared in the
                              <code nobreak="false">xsl:with-param/@as</code> attribute, or the
                              <code nobreak="false">xsl:param/@as</code> attribute of the corresponding parameter on
                           the target named template, whichever is more restrictive, defaulting to
                              <code nobreak="false">item()*</code> if both are absent.</p></item></olist><note><p>Calling <elcode>xsl:call-template</elcode> will usually make stylesheet code
                        unstreamable if a streamed node is passed explicitly or implicitly to the
                        called template, unless it is atomized by declaring the expected type to be
                        atomic.</p></note></div3><div3 id="streamability-xsl-choose"><head>Streamability of <elcode>xsl:choose</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:choose</elcode> follow the <termref def="dt-general-streamability-rules"/>. 
                     The <termref def="dt-operand-role">operand roles</termref> and their 
                     <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">test</code> attribute of contained <elcode>xsl:when</elcode>
                           elements (usage <termref def="dt-inspection"/>).</p></item><item><p>The sequence constructors <phrase diff="add" at="2022-11-01">and <code nobreak="false">select</code> expressions</phrase>
                           contained within <elcode>xsl:when</elcode> and
                              <elcode>xsl:otherwise</elcode> child elements (usage <termref def="dt-transmission"/>). 
                           These <phrase diff="del" at="2022-11-01">sequence constructor</phrase> operands form a
                              <termref def="dt-choice-operand-group"/>.</p></item></olist><note><p>The effect is to allow either of the following:</p><olist><item><p>Any or all of the sequence constructors <phrase diff="add" at="2022-11-01">and <code nobreak="false">select</code> expressions</phrase>
                              in <elcode>xsl:when</elcode> and
                                 <elcode>xsl:otherwise</elcode> branches may be <termref def="dt-consuming"/>,  in
                              which case the <code nobreak="false">test</code> expressions must all be <termref def="dt-motionless"/>.</p></item><item><p>Any one of the <code nobreak="false">test</code> expressions may be <termref def="dt-consuming"/>, 
                              in which case all the other <code nobreak="false">test</code> expressions, and all the 
                              sequence constructors <phrase diff="add" at="2022-11-01">and <code nobreak="false">select</code> expressions</phrase>, 
                              must be <termref def="dt-motionless"/>.</p></item></olist></note></div3><div3 id="streamability-xsl-comment"><head>Streamability of <elcode>xsl:comment</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:comment</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-copy"><head>Streamability of <elcode>xsl:copy</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:copy</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The expression in the <code nobreak="false">select</code> attribute, defaulting to a
                           context item expression (<code nobreak="false">.</code>) (usage <termref def="dt-inspection"/>)</p></item><item><p>The contained sequence constructor (usage <termref def="dt-absorption"/>), assessed with <termref def="dt-context-posture"/> and context item
                           type based on the <code nobreak="false">select</code> expression if present, or the outer
                           focus otherwise.</p></item><item><p>Any <xtermref spec="XT40" ref="dt-attribute-set">attribute sets</xtermref> named in the
                           <code nobreak="false">use-attribute-sets</code> attribute (usage irrelevant, but can be taken as <termref def="dt-inspection"/>).</p><note><p>In practice, a reference to an attribute set that is <termref def="dt-declared-streamable"/> does not
                           affect the analysis, while a reference to any other attribute set makes the <elcode>xsl:copy</elcode> instruction
                           <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></note></item></olist><note><p>The effect of these rules is that when a <code nobreak="false">select</code>
                     attribute is present, the sequence constructor contained by the <elcode>xsl:copy</elcode>
                     instruction is deemed to be a <termref def="dt-higher-order-operand"/> of the instruction,
                     even though it can only be evaluated once.</p><p>This has the practical consequence that the following example is not <termref def="dt-guaranteed-streamable"/>,
                  even though it is possible to imagine a strategy for streamed evaluation:</p><eg role="xslt-instruction" xml:space="preserve">
 &lt;xsl:for-each-group select="product" group-adjacent="@category"&gt;
     &lt;xsl:copy select=".."&gt;
         &lt;xsl:copy-of select="current-group()"/&gt;
     &lt;/xsl:copy&gt;
 &lt;/xsl:for-each-group&gt;</eg><p>A workaround in this case might be to rewrite the code as follows:</p><eg role="xslt-instruction" xml:space="preserve">
 &lt;xsl:for-each-group select="product" group-adjacent="@category"&gt;
     &lt;xsl:element name="{name(..)}" namespace="{namespace-uri(..)}"&gt;
         &lt;xsl:copy-of select="current-group()"/&gt;
     &lt;/xsl:element&gt;
 &lt;/xsl:for-each-group&gt;</eg></note></div3><div3 id="streamability-xsl-copy-of"><head>Streamability of <elcode>xsl:copy-of</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:copy-of</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-document"><head>Streamability of <elcode>xsl:document</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:document</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-element"><head>Streamability of <elcode>xsl:element</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:element</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">name</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">namespace</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>Any <xtermref spec="XT40" ref="dt-attribute-set">attribute sets</xtermref> named in the
                           <code nobreak="false">use-attribute-sets</code> attribute (usage irrelevant, but can be taken as <termref def="dt-inspection"/>).</p><note><p>In practice, a reference to an attribute set that is <termref def="dt-declared-streamable"/> does not
                           affect the analysis, while a reference to any other attribute set makes the <elcode>xsl:element</elcode> instruction
                           <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></note></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-evaluate"><head>Streamability of <elcode>xsl:evaluate</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:evaluate</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">xpath</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">context-item</code> expression (usage <termref def="dt-navigation"/>)</p></item><item><p>The <code nobreak="false">with-params</code> expression (usage <termref def="dt-navigation"/>)</p></item><item><p>The <code nobreak="false">base-uri</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">namespace-context</code> expression (usage <termref def="dt-inspection"/>)</p></item><item><p>The <code nobreak="false">schema-aware</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> attributes and contained 
                          <xtermref spec="XT40" ref="dt-sequence-constructor">sequence constructors</xtermref> of any
                              <elcode>xsl:with-param</elcode> child elements (usage <termref def="dt-type-determined-usage">type-determined</termref>, based on the
                           type in the <code nobreak="false">xsl:with-param/@as</code> attribute, defaulting to
                              <code nobreak="false">item()*</code>)</p></item></olist><note><p>In practice, code containing an <elcode>xsl:evaluate</elcode> instruction
                        will usually be streamable provided that streamed nodes are not passed to
                        the dynamic expression either as the context item or as the value of a
                        parameter.</p></note></div3><div3 id="streamability-xsl-fallback"><head>Streamability of <elcode>xsl:fallback</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                        <elcode>xsl:fallback</elcode> instruction depend on whether the processor is
                     performing fallback (which is known statically).</p><p>If the processor is performing fallback, then the <termref def="dt-posture"/>
                     and <termref def="dt-sweep"/> of the <elcode>xsl:fallback</elcode> instruction
                     are the posture and sweep of the contained sequence constructor.</p><p>If the processor is not performing fallback, then the instruction is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></div3><div3 id="streamability-xsl-for-each"><head>Streamability of <elcode>xsl:for-each</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                        <elcode>xsl:for-each</elcode> instruction are the first of the following
                     that applies:</p><olist><item><p>If the <code nobreak="false">select</code> expression is <termref def="dt-grounded"/>,
                           then the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                              <elcode>xsl:for-each</elcode> instruction follow the <termref def="dt-general-streamability-rules"/>, with the <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (the <termref def="dt-operand-usage"/> is irrelevant, but can be taken as
                                    <termref def="dt-inspection"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage
                                    <termref def="dt-transmission"/>). This is a <termref def="dt-higher-order-operand">higher-order operand</termref>;
                                 its context posture is <termref def="dt-grounded"/>.</p></item><item><p>Any attribute value templates appearing in attributes of a child
                                    <elcode>xsl:sort</elcode> instruction (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> expression or contained sequence
                                 constructor of any <elcode>xsl:sort</elcode> children, assessed
                                 with a <termref def="dt-context-posture"/> of <termref def="dt-grounded"/> (usage <termref def="dt-absorption"/>).
                                 These are <termref def="dt-higher-order-operand">higher-order
                                    operands</termref>; their context posture is <termref def="dt-grounded"/>.</p></item></olist></item><item><p>If there is an <elcode>xsl:sort</elcode> child element, then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If the <termref def="dt-posture"/> of the
                              <code nobreak="false">select</code> expression is <termref def="dt-crawling"/> and the
                              <termref def="dt-sweep"/> of the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> is <termref def="dt-consuming"/>, then
                              <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>. </p></item><item><p>Otherwise:</p><olist><item><p>The <termref def="dt-posture"/> of the instruction is the <termref def="dt-posture"/> of the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>, assessed with the <termref def="dt-context-posture"/>
                                 and context item type set to the <termref def="dt-posture"/> and
                                 type of the <code nobreak="false">select</code> expression.</p></item><item><p>The <termref def="dt-sweep"/> of the instruction is the wider of
                                 the <termref def="dt-sweep"/> of the <code nobreak="false">select</code> expression
                                 and the <termref def="dt-sweep"/> of the contained 
                                <xtermref spec="XT40" ref="dt-sequence-constructor"/>.</p><note><p>The ordering of sweep values is in increasing order: <termref def="dt-motionless"/>, <termref def="dt-consuming"/>,
                                       <termref def="dt-free-ranging"/>.</p></note></item></olist><note><p>Because the body of the <elcode>xsl:for-each</elcode> instruction is a
                                 <termref def="dt-higher-order-operand"/> of the instruction, any
                              variable reference within the body that is bound to a 
                             <termref def="dt-streaming-parameter"/> of a containing <xtermref spec="XT40" ref="dt-stylesheet-function"/> will not be singular, which in many
                              cases will make the entire function non-streamable.</p></note></item></olist></div3><div3 id="streamability-xsl-for-each-group"><head>Streamability of <elcode>xsl:for-each-group</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                        <elcode>xsl:for-each-group</elcode> instruction are the first of the
                     following that applies:</p><olist><item><p>If the <code nobreak="false">select</code> expression is <termref def="dt-grounded"/>,
                           then the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                              <elcode>xsl:for-each-group</elcode> instruction follow the <termref def="dt-general-streamability-rules"/>, with the <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (the <termref def="dt-operand-usage"/> is irrelevant, but can be taken as
                                    <termref def="dt-inspection"/>)</p></item><item><p>The <code nobreak="false">collation</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>Any attribute value templates appearing in attributes of a child
                                    <elcode>xsl:sort</elcode> instruction (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">group-by</code> or <code nobreak="false">group-adjacent</code>
                                 expression, assessed with a <termref def="dt-context-posture"/> of
                                    <termref def="dt-grounded"/> (usage <termref def="dt-absorption"/>).</p></item><item><p>The <code nobreak="false">select</code> expression or contained sequence
                                 constructor of any <elcode>xsl:sort</elcode> children, assessed
                                 with a <termref def="dt-context-posture"/> of <termref def="dt-grounded"/> (usage <termref def="dt-absorption"/>).</p></item><item><p>The <code nobreak="false">group-starting-with</code> or
                                    <code nobreak="false">group-ending-with</code> patterns if present; these are
                                    <termref def="dt-higher-order-operand">higher-order
                                    operands</termref> with usage <termref def="dt-inspection"/>.</p></item></olist></item><item><p>If there is a <code nobreak="false">group-by</code> attribute and the instruction is not a child of
                                 <elcode>xsl:fork</elcode>, then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If there is a <code nobreak="false">group-by</code>
                              or
                           <code nobreak="false">group-adjacent</code> attribute that is not <termref def="dt-motionless"/>, then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If there is an <elcode>xsl:sort</elcode> child element 
                           and the instruction is not a child of <elcode>xsl:fork</elcode>, then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If the <termref def="dt-posture"/> of the
                              <code nobreak="false">select</code> expression is <termref def="dt-crawling"/> and the
                              <termref def="dt-sweep"/> of the contained 
                          <xtermref spec="XT40" ref="dt-sequence-constructor"/> is <termref def="dt-consuming"/>, then
                              <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>Otherwise:</p><olist><item><p>The <termref def="dt-posture"/> of the instruction is the <termref def="dt-posture"/> of 
                                the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>, assessed with the <termref def="dt-context-posture"/>
                                 and context item type set to the <termref def="dt-posture"/> and
                                 type of the <code nobreak="false">select</code> expression.</p></item><item><p>The <termref def="dt-sweep"/> of the instruction is the wider of
                                 the <termref def="dt-sweep">sweeps</termref> of the
                                    <code nobreak="false">select</code> expression and the contained 
                                <xtermref spec="XT40" ref="dt-sequence-constructor"/>, where the ordering of
                                 increasing width is <termref def="dt-motionless"/>, <termref def="dt-consuming"/>, <termref def="dt-free-ranging"/>.</p></item></olist><note><p>Because the body of the <elcode>xsl:for-each-group</elcode>
                              instruction is a <termref def="dt-higher-order-operand"/> of the
                              instruction, any variable reference within the body that is bound to a
                                 <termref def="dt-streaming-parameter"/> of a containing 
                             <xtermref spec="XT40" ref="dt-stylesheet-function"/> will not be singular, which in many
                              cases will make the entire function non-streamable.</p></note></item></olist><note><p>The above rules do not explicitly mention any
                        constraints on the presence or absence of a call on the
                           <function>current-group</function> function. In practice, however, this
                        plays an important role. In the most common case, the <code nobreak="false">select</code>
                        expression of <elcode>xsl:for-each-group</elcode> is likely to be striding,
                        for example an expression such as <code nobreak="false">select="*"</code>. Any call on
                           <function>current-group</function> associated with this
                           <elcode>xsl:for-each-group</elcode> instruction will ordinarily be
                           <termref def="dt-striding"/> and <termref def="dt-consuming"/>, which is
                        consistent with streaming provided there is only one such call, and if it
                        appears in a suitable context (for example, not within a predicate). If
                        there is more than one call, or if it appears in an unsuitable context (for
                        example, within a predicate), then this will have the same effect as
                        multiple appearances of other consuming expressions: the construct as a
                        whole will be free-ranging. These rules are not spelled out explicitly, but
                        rather emerge as a consequence of the general streamability rules.</p></note></div3><div3 id="streamability-xsl-fork"><head>Streamability of <elcode>xsl:fork</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:fork</elcode> are the first of the following that applies:</p><olist><item><p>If there is a child <elcode>xsl:for-each-group</elcode> instruction, then
                           the <termref def="dt-posture"/> and the <termref def="dt-sweep"/> of that
                           instruction.</p></item><item><p>If there are no child <elcode>xsl:sequence</elcode> instructions (other than
                              <elcode>xsl:fallback</elcode>), then <termref def="dt-grounded"/> and
                              <termref def="dt-motionless"/>.</p></item><item><p>If there is a child <elcode>xsl:sequence</elcode> instruction whose
                              <termref def="dt-posture"/> is not <termref def="dt-grounded"/>, then
                              <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>Otherwise, the <termref def="dt-posture"/> is <termref def="dt-grounded"/>, and the <termref def="dt-sweep"/> is the widest sweep of the
                              <elcode>xsl:sequence</elcode> child instructions.</p></item></olist><note><p>None of the branches of <elcode>xsl:fork</elcode> can return streamed nodes.
                        The reason for this is that <elcode>xsl:fork</elcode> has to assemble its
                        results in the correct order, and streamed nodes cannot be re-ordered.</p><p>The effect of the rules is that each of the child
                           <elcode>xsl:sequence</elcode> instructions can independently consume the
                        streamed input document, provided that the result of each child instruction
                        is <termref def="dt-grounded"/>.</p><p>Thus the following example is streamable:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:fork&gt;
   &lt;xsl:sequence select="copy-of(author)"/&gt;
   &lt;xsl:sequence select="copy-of(editor)"/&gt;
&lt;/xsl:fork&gt;</eg><p>While the following is not streamable, because it returns streamed nodes in
                        an order that might not be document order:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:fork&gt;
   &lt;xsl:sequence select="author"/&gt;
   &lt;xsl:sequence select="editor"/&gt;
&lt;/xsl:fork&gt;</eg></note></div3><div3 id="streamability-xsl-if"><head>Streamability of <elcode>xsl:if</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:if</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">test</code> expression (usage <termref def="dt-inspection"/>)</p></item><item diff="add" at="2022-11-01"><p>The <code nobreak="false">then</code> and <code nobreak="false">else</code> expressions and the 
                           contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-transmission"/>).
                        These operands form a <termref def="dt-choice-operand-group"/></p></item></olist><note diff="add" at="2022-11-01"><p>The effect is to allow either of the following:</p><olist><item><p>The <code nobreak="false">test</code> expression may be <termref def="dt-motionless"/>, in which case any or all
                        of the <code nobreak="false">then</code> and <code nobreak="false">else</code> expressions, and the containing sequence constructor, may
                        be <termref def="dt-consuming"/>.</p></item><item><p>The <code nobreak="false">test</code> expression may be <termref def="dt-consuming"/>, in which case
                           the <code nobreak="false">then</code> and <code nobreak="false">else</code> expressions, and the containing sequence constructor, must
                           all be <termref def="dt-motionless"/>.</p></item></olist></note></div3><div3 id="streamability-xsl-iterate"><head>Streamability of <elcode>xsl:iterate</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                        <elcode>xsl:iterate</elcode> instruction are the first of the following that
                     applies:</p><olist><item><p>If the <code nobreak="false">select</code> expression is <termref def="dt-grounded"/>,
                           then the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the
                              <elcode>xsl:iterate</elcode> instruction follow the <termref def="dt-general-streamability-rules"/>, with the <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (the <termref def="dt-operand-usage"/> is irrelevant, but can be taken as
                                    <termref def="dt-inspection"/>)</p></item><item><p>The <code nobreak="false">select</code> expression or contained sequence
                                 constructor of any <elcode>xsl:param</elcode> children (usage
                                    <termref def="dt-navigation"/>)</p></item><item><p>The sequence constructor contained within the
                                    <elcode>xsl:iterate</elcode> instruction itself, assessed with
                                 its context item type and <termref def="dt-context-posture"/> based
                                 on the <code nobreak="false">select</code> expression (usage <termref def="dt-transmission"/>)</p></item><item><p>The <code nobreak="false">select</code> expression or contained sequence
                                 constructor of any child <elcode>xsl:on-completion</elcode>
                                 element, assessed with a context item type of <code nobreak="false">xs:error</code>
                                 and a <termref def="dt-context-posture"/> of <termref def="dt-roaming"/> to reflect the fact that any attempt to
                                 reference the context item within the
                                    <elcode>xsl:on-completion</elcode> element is an error (usage
                                    <termref def="dt-transmission"/>)</p><note><p>The <code nobreak="false">on-completion</code>
                                    element can cause the instruction to become non-streamable if,
                                    for example, it contains a call on
                                       <function>current-group</function> or a variable reference
                                    bound to a <termref def="dt-streaming-parameter"/>.</p></note></item></olist></item><item><p>If there is an <elcode>xsl:param</elcode> child whose initializing
                              <code nobreak="false">select</code> expression or 
                          <xtermref spec="XT40" ref="dt-sequence-constructor"/> is not <termref def="dt-grounded"/>
                           and <termref def="dt-motionless"/>, then <termref def="dt-roaming"/> and
                              <termref def="dt-free-ranging"/>.</p></item><item><p>If there is an <elcode>xsl:on-completion</elcode> child whose
                              <code nobreak="false">select</code> expression or <xtermref spec="XT40" ref="dt-sequence-constructor"/> is not <termref def="dt-grounded"/>
                           and <termref def="dt-motionless"/>, then <termref def="dt-roaming"/> and
                              <termref def="dt-free-ranging"/>.</p></item><item><p>If the <termref def="dt-posture"/> of the
                              <code nobreak="false">select</code> expression is <termref def="dt-crawling"/> and the
                              <termref def="dt-sweep"/> of the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> is <termref def="dt-consuming"/>, then
                              <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>Otherwise:</p><olist><item><p>The <termref def="dt-posture"/> of the instruction is the <termref def="dt-posture"/> of the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>, assessed with the <termref def="dt-context-posture"/>
                                 and context item type set to the <termref def="dt-posture"/> and
                                 type of the <code nobreak="false">select</code> expression.</p></item><item><p>The <termref def="dt-sweep"/> of the instruction is the wider of
                                 the <termref def="dt-sweep">sweeps</termref> of the <code nobreak="false">select</code> expression and the
                                    contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>,
                                 where the ordering of increasing width is <termref def="dt-motionless"/>, <termref def="dt-consuming"/>, <termref def="dt-free-ranging"/>.</p></item></olist></item></olist><note><p>If any <elcode>xsl:break</elcode> or <elcode>xsl:next-iteration</elcode>
                        instructions appear within the sequence constructor, their <termref def="dt-posture"/> and <termref def="dt-sweep"/> will be assessed in the
                        course of evaluating the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the sequence constructor, by reference to the rules
                        in <specref ref="streamability-xsl-break"/> and <specref ref="streamability-xsl-next-iteration"/> respectively.</p></note><note><p>Because the body of the <elcode>xsl:iterate</elcode> instruction is a
                           <termref def="dt-higher-order-operand"/> of the instruction, any variable
                        reference within the body that is bound to a <termref def="dt-streaming-parameter"/> 
                       of a containing <xtermref spec="XT40" ref="dt-stylesheet-function"/> will not be singular, which in many cases
                        will make the entire function non-streamable.</p></note><!--
                        
                        <p>The operands of the <elcode>xsl:iterate</elcode> instruction are 
                           divided into three groups, as follows.</p>
                        
                        <olist>
                        <item><p>The outer-focus operands are the following (these
                           are all evaluated with the same focus as the <elcode>xsl:iterate</elcode> 
                           instruction itself):</p>
                        
                        <ulist>
                           <item><p>The <code>select</code> expression</p></item>
                           <item><p>Any <code>select</code> expression of a child 
                              <elcode>xsl:param</elcode> element;</p></item>
                           <item><p>Any <termref def="dt-sequence-constructor"/> appearing as the content of a 
                              child <elcode>xsl:param</elcode> element.</p></item>
                        </ulist></item>
                        
                        <item><p>The inner-focus operands of the <elcode>xsl:iterate</elcode> instruction are the
                           following (these are all evaluated with a focus based on the sequence
                           selected by the <code>select</code> expression):</p>
                        
                        <ulist>
                           <item><p>The contained <termref def="dt-sequence-constructor"/>
                           (including any contained <elcode>xsl:break</elcode> instructions).</p></item>
                           
                        </ulist></item>
                        
                        <item><p>The no-focus operands of the <elcode>xsl:iterate</elcode> instruction are the
                        following (these are all evaluated with an absent focus):</p>
                        
                        <ulist>
                           <item><p>The <code>select</code> expression of any child 
                              <elcode>xsl:on-completion</elcode> element;</p></item>
                           <item><p>The <termref def="dt-sequence-constructor"/> appearing as the content of any 
                              child <elcode>xsl:on-completion</elcode> element.</p></item>
                        </ulist></item>
                           
                        </olist>
                        
                        <p>The <termref def="dt-sweep">sweep</termref> of the instruction is the
                        first of the following that applies:</p>
                        
                        <olist>
                           <item><p>If all outer-focus operands are <termref def="dt-motionless"/>, and if no operand
                              contains (at any level) a reference to a variable declared in the <code>bind-group</code>
                              attribute of an <elcode>xsl:for-each-group</elcode> instruction that is an ancestor of this
                              <elcode>xsl:iterate</elcode> instruction, then <termref def="dt-motionless"/>.</p></item>
                           <item diff="del" at="Q"><p>If all the following conditions are satisfied, then group-consuming:</p>
                              <olist>
                                 <item><p>the contained sequence constructor is <termref def="dt-motionless"/> or <termref def="dt-consuming"/></p></item>
                                 <item><p>the <code>select</code> expression is a variable reference
                                    to a variable declared in the <code>bind-group</code> attribute of
                                    the innermost ancestor <elcode>xsl:for-each-group</elcode>
                                    instruction.</p></item>
                                 <item><p>all other inner-focus and outer-focus operands are <termref def="dt-motionless"/>.</p></item>
                              </olist>
                           </item>
                           <item><p>If all the following conditions are satisfied, then <termref def="dt-consuming"/>:</p>
                              <olist>
                                 <item><p>the contained sequence constructor is <termref def="dt-motionless"/> or <termref def="dt-consuming"/></p></item>
                                 <item><p>the <code>select</code> expression has 
                                    <termref def="dt-striding"/> <termref def="dt-posture"/>.</p></item>
                                 <item><p>all other inner-focus and outer-focus operands are <termref def="dt-motionless"/>.</p></item>
                              </olist>
                           </item>
                           <item><p>Otherwise, <termref def="dt-free-ranging"/>.</p></item>
                        </olist>
                        <note><p>It is a consequence of the rules given that if an <elcode>xsl:iterate</elcode>
                        instruction is to be streamable, then all related <elcode>xsl:param</elcode>, 
                        <elcode>xsl:on-completion</elcode>,
                        <elcode>xsl:break</elcode>, and <elcode>xsl:next-iteration</elcode> elements
                        must be <termref def="dt-motionless"/>.</p></note>
                        --></div3><div3 id="streamability-xsl-map"><head>Streamability of <elcode>xsl:map</elcode></head><changes><change issue="2036">The special rule allowing <elcode>xsl:map</elcode>
                      to have multiple consumable operands does not apply if duplicate keys are
                     permitted.</change></changes><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the <elcode>xsl:map</elcode> instruction are determined
                     by the first of the following that applies:</p><olist><item><p>If the sequence constructor within the instruction consists exclusively
                           of <elcode>xsl:map-entry</elcode> instructions (and
                              <elcode>xsl:fallback</elcode> instructions, which are ignored),
                           and the <code nobreak="false">duplicates</code> attribute is absent,
                           then:</p><olist><item><p>If any of these <elcode>xsl:map-entry</elcode> children is <termref def="dt-roaming"/> or <termref def="dt-free-ranging"/>, then
                                    <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>;</p></item><item><p>Otherwise, <termref def="dt-grounded"/> and the widest sweep of the
                                    <elcode>xsl:map-entry</elcode> children.</p></item></olist></item><item><p>Otherwise, the <termref def="dt-posture"/> and <termref def="dt-sweep"/>
                           of the <elcode>xsl:map</elcode> instruction are the posture and sweep of
                           the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>.</p></item></olist><note><p>See discussion in <specref ref="maps-streaming"/>.</p><p>The effect of the rules is that it is possible to compute multiple map
                        entries in a single pass of the streamed input document. For example, the
                        following is streamable:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:map&gt;
  &lt;xsl:map-entry key="'authors'" select="copy-of(author)"/&gt;
  &lt;xsl:map-entry key="'editors'" select="copy-of(editor)"/&gt;
&lt;/xsl:map&gt;  
</eg><p>The call on <function>copy-of</function> is necessary to ensure that the
                        content of the map entry is grounded; it is not possible to create a map
                        whose entries contain references to streamed nodes.</p><p>This rule does not apply when duplicate keys are permitted, because in that
                     situation the child <elcode>xsl:map-entry</elcode> instructions generally need
                     to be evaluated in the order they are written, rather than in the order their
                     operands are encountered.</p></note></div3><div3 id="streamability-xsl-map-entry"><head>Streamability of <elcode>xsl:map-entry</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:map-entry</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">key</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-navigation"/>)</p><note><p>This effectively means that the <code nobreak="false">select</code>
                              expression must not return nodes from a streamed input document.</p></note></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>
                           (usage <termref def="dt-navigation"/>).</p></item></olist></div3><div3 id="streamability-xsl-merge"><head>Streamability of <elcode>xsl:merge</elcode></head><note><p>This section is concerned with the (not very interesting) impact of the
                           <elcode>xsl:merge</elcode> instruction on the streamability of its
                        containing template rule or <elcode>xsl:source-document</elcode> instruction.</p><p>For the (more important) rules concerning the way in which
                           <elcode>xsl:merge</elcode> performs streamed processing of its own
                        inputs, see <specref ref="streamable-merging"/>.</p></note><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of <elcode>xsl:merge</elcode> are as follows:</p><olist><item><p>If every <elcode>xsl:merge-source</elcode> child element satisfies all
                           the following conditions:</p><olist><item><p>The expression in the <code nobreak="false">for-each-item</code> attribute is
                                 either absent, or <termref def="dt-grounded"/> and <termref def="dt-motionless"/>;</p></item><item><p>The expression in the <code nobreak="false">for-each-source</code> attribute is
                                 either absent, or <termref def="dt-grounded"/> and <termref def="dt-motionless"/>;</p></item><item><p>Either at least one of the attributes <code nobreak="false">for-each-item</code>
                                 and <code nobreak="false">for-each-source</code> is present, or the expression in
                                 the <code nobreak="false">select</code> attribute is <termref def="dt-grounded"/>
                                 and <termref def="dt-motionless"/></p></item></olist><p>then the <elcode>xsl:merge</elcode> instruction is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item><item><p>Otherwise, the <elcode>xsl:merge</elcode> instruction is 
                           <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item></olist><!--
                  <p>If all <elcode>xsl:merge-source</elcode> children are <termref def="dt-motionless"/>
                     then the instruction is <phrase diff="add" at="R-bug24535"><termref def="dt-grounded"/> and</phrase> 
                     <termref def="dt-motionless"/>.</p>
                  <p>Otherwise, the instruction is <phrase diff="add" at="R-bug24535"><termref def="dt-roaming"/> and</phrase> <termref def="dt-free-ranging"/>.</p>
                     
                     --></div3><div3 id="streamability-xsl-message"><head>Streamability of <elcode>xsl:message</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:message</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">terminate</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">error-code</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-namespace"><head>Streamability of <elcode>xsl:namespace</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:namespace</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">name</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-next-iteration"><head>Streamability of <elcode>xsl:next-iteration</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:next-iteration</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression or <xtermref spec="XT40" ref="dt-sequence-constructor"/> content of any contained
                              <elcode>xsl:with-param</elcode> child element: its <termref def="dt-operand-usage"/> is the <termref def="dt-type-determined-usage"/> based on the type declared in the
                              <code nobreak="false">xsl:with-param/@as</code> attribute, or the
                              <code nobreak="false">xsl:param/@as</code> attribute of the corresponding parameter on
                           the containing <elcode>xsl:iterate</elcode> instruction, whichever is
                           more restrictive, defaulting to <code nobreak="false">item()*</code> if both are
                           absent.</p></item></olist></div3><div3 id="streamability-xsl-next-match"><head>Streamability of <elcode>xsl:next-match</elcode></head><p>The rules are the same as for <elcode>xsl:apply-imports</elcode>: see <specref ref="streamability-xsl-apply-imports"/>.</p></div3><div3 id="streamability-xsl-number"><head>Streamability of <elcode>xsl:number</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:number</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">value</code> attribute if present: usage <termref def="dt-absorption"/></p></item><item><p>The <code nobreak="false">select</code> attribute if there is
                           no <code nobreak="false">value</code> attribute, defaulting to the context item
                           expression (<code nobreak="false">.</code>) if the <code nobreak="false">select</code> attribute is also
                           absent: usage <termref def="dt-navigation"/></p></item><item><p>The attribute value templates in the <code nobreak="false">format</code>,
                              <code nobreak="false">lang</code>, <code nobreak="false">letter-value</code>, <code nobreak="false">ordinal</code>,
                              <code nobreak="false">start-at</code>, <code nobreak="false">grouping-separator</code>, and
                              <code nobreak="false">grouping-size</code> attributes (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">from</code> and <code nobreak="false">count</code> patterns if present. These can be treated as <termref def="dt-higher-order-operand">higher-order operands</termref> with
                              usage <termref def="dt-inspection"/>, though neither of these
                              properties affects the outcome.</p></item></olist><note><p>The effect of these rules is that <elcode>xsl:number</elcode> can be used
                        for formatting of numbers supplied directly using the <code nobreak="false">value</code>
                        attribute, and also for numbering of nodes in a non-streamed document, but
                        it cannot be used for numbering streamed nodes.</p><p>In practice the rules depend very little on the <code nobreak="false">from</code> and
                           <code nobreak="false">count</code> patterns. This is because when the instruction is
                        applied to a streamed node, the instruction will be <termref def="dt-free-ranging"/> regardless of these patterns; while if it is
                        applied to a grounded node or atomic item, the instruction will normally be
                           <termref def="dt-motionless"/> regardless of the values of these
                        patterns. The pattern does matter,
                           however, if it contains a variable reference bound to a <termref def="dt-streaming-parameter"/>;
                           because such a reference occurs within a <termref def="dt-higher-order-operand"/> of the <elcode>xsl:number</elcode>
                           instruction, its presence automatically makes the variable reference
                              <termref def="dt-free-ranging"/>, which in turn ensures that the
                           containing stylesheet function is not <termref def="dt-guaranteed-streamable"/>.</p></note></div3><div3 id="streamability-xsl-on-empty"><head>Streamability of <elcode>xsl:on-empty</elcode></head><p>The streamability rules for the <elcode>xsl:on-empty</elcode> instruction are
                     the same as the rules for <elcode>xsl:sequence</elcode>: see <specref ref="streamability-xsl-sequence"/>.</p><note><p>The streamability rules for a sequence constructor containing an
                           <elcode>xsl:on-empty</elcode> instruction are given in <specref ref="classifying-sequence-constructors"/>.</p></note></div3><div3 id="streamability-xsl-on-non-empty"><head>Streamability of <elcode>xsl:on-non-empty</elcode></head><p>The streamability rules for the <elcode>xsl:on-non-empty</elcode> instruction
                     are the same as the rules for <elcode>xsl:sequence</elcode>: see <specref ref="streamability-xsl-sequence"/>.</p><note><p>The streamability rules for a sequence constructor containing an
                           <elcode>xsl:on-non-empty</elcode> instruction are given in <specref ref="classifying-sequence-constructors"/>.</p></note></div3><div3 id="streamability-xsl-perform-sort"><head>Streamability of <elcode>xsl:perform-sort</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:perform-sort</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The expression in the <code nobreak="false">select</code> attribute: usage <termref def="dt-navigation"/> (because order is not preserved)</p></item><item><p>The expressions in the attribute value templates of
                              <elcode>xsl:sort</elcode> child elements: usage <termref def="dt-absorption"/></p></item><item><p>The expression in the <code nobreak="false">select</code> attribute or contained sequence constructor in child
                              <elcode>xsl:sort</elcode> child elements, with usage <termref def="dt-absorption"/>, assessed with <termref def="dt-context-posture"/> based on the
                           expression in the <code nobreak="false">xsl:perform-sort/@select</code> attribute.</p></item></olist><note><p>In practice, the <elcode>xsl:perform-sort</elcode> instruction cannot be
                        used to sort nodes from the streamed input document, but it can be used to
                        sort atomic items or <termref def="dt-grounded"/> nodes, for example a copy
                        of nodes from the streamed document made using the
                           <function>copy-of</function> function.</p></note></div3><div3 id="streamability-xsl-processing-instruction"><head>Streamability of <elcode>xsl:processing-instruction</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:processing-instruction</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">name</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-record"><head>Streamability of <elcode>xsl:record</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the <elcode>xsl:record</elcode> instruction are determined
                        by the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the equivalent <elcode>xsl:map</elcode> instruction 
                        as described in the definition of <elcode>xsl:record</elcode></p></div3><div3 id="streamability-xsl-result-document"><head>Streamability of <elcode>xsl:result-document</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:result-document</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">href</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The attribute value templates containing serialization properties (usage
                              <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-sequence"><head>Streamability of <elcode>xsl:sequence</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:sequence</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> attribute value template (usage <termref def="dt-transmission"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-transmission"/>).</p></item></olist></div3><div3 id="streamability-xsl-stream"><head>Streamability of <elcode>xsl:source-document</elcode></head><note><p>The concern here is with the impact of <elcode>xsl:source-document</elcode> on any
                        streaming template, or ancestor <elcode>xsl:source-document</elcode> instruction, and
                        not with the streamed processing of the document accessed using the
                           <code nobreak="false">xsl:source-document/@href</code> attribute.</p><p>The streamability of the document opened by the <elcode>xsl:source-document</elcode>
                        instruction is not assessed using the rules in this section; it depends only
                        on the streamability properties of the contained sequence constructor, as
                        described in <specref ref="source-document-streamability"/>.</p></note><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:source-document</elcode> are the first of the following that applies:</p><olist><item><p>If the contained sequence constructor contains, at any depth, a call on the
                                 <function>current-group</function> function whose nearest
                              containing <elcode>xsl:for-each-group</elcode> instruction
                           exists and is an ancestor of the <elcode>xsl:source-document</elcode> instruction,
                           then <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If the contained sequence constructor contains, at any depth, a call on the
                                 <function>current-merge-group</function> function whose nearest
                              containing <elcode>xsl:merge</elcode> instruction exists and
                           is an ancestor of the <elcode>xsl:source-document</elcode> instruction, then
                              <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>Otherwise, the <termref def="dt-posture"/> is <termref def="dt-grounded"/> and the <termref def="dt-sweep"/> is the <termref def="dt-sweep"/> of
                           the <code nobreak="false">href</code> attribute value template.</p></item></olist><!--<note>
                     <p>The effective prohibition on grouping variable references is largely to
                        avoid complicating the analysis. It means that posture and sweep for the
                        constructs within <elcode>xsl:source-document</elcode> need to be computed only with
                        respect to the <elcode>xsl:source-document</elcode> instruction itself, and not with
                        respect to the containing template, or an outer <elcode>xsl:source-document</elcode>
                        instruction.</p>
                  </note>--></div3><div3 id="streamability-xsl-switch" diff="add" at="2022-11-01"><head>Streamability of <elcode>xsl:switch</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                     <elcode>xsl:switch</elcode> follow the <termref def="dt-general-streamability-rules"/>. 
                     The <termref def="dt-operand-role">operand roles</termref> and their 
                     <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> attribute of the <elcode>xsl:switch</elcode>
                           elements (usage <termref def="dt-absorption"/>).</p></item><item><p>The <code nobreak="false">test</code> attribute of contained <elcode>xsl:when</elcode>
                           elements (usage <termref def="dt-absorption"/>).</p></item><item><p>The sequence constructors and <code nobreak="false">select</code> expressions
                           contained within <elcode>xsl:when</elcode> and
                           <elcode>xsl:otherwise</elcode> child elements (usage <termref def="dt-transmission"/>). 
                           These operands form a
                           <termref def="dt-choice-operand-group"/>.</p></item></olist><note><p>The effect is to allow any of the following:</p><olist><item><p>The <code nobreak="false">select</code> expression of the <elcode>xsl:switch</elcode> instruction may be
                              <termref def="dt-consuming"/>, in
                              which case all the other operands must be <termref def="dt-motionless"/>.</p></item><item><p>Any one of the <code nobreak="false">test</code> expressions may be <termref def="dt-consuming"/>, 
                              in which case all the other operands must be <termref def="dt-motionless"/>.</p></item><item><p>Any or all of the sequence constructors and <code nobreak="false">select</code> expressions
                              in <elcode>xsl:when</elcode> and
                              <elcode>xsl:otherwise</elcode> branches may be <termref def="dt-consuming"/>,  in
                              which case the <code nobreak="false">test</code> expressions and the <code nobreak="false">select</code> of
                              the <elcode>xsl:switch</elcode> instruction must all be <termref def="dt-motionless"/>.</p></item></olist></note></div3><div3 id="streamability-xsl-text"><head>Streamability of <elcode>xsl:text</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:text</elcode> follow the <termref def="dt-general-streamability-rules"/>. 
                    The <termref def="dt-operand-role">operand roles</termref> and their 
                    <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">separator</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> 
                          (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-try"><head>Streamability of <elcode>xsl:try</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep">sweep</termref> of the <elcode>xsl:try</elcode> instruction
                     follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression or contained 
                          <xtermref spec="XT40" ref="dt-sequence-constructor"/> of the <elcode>xsl:try</elcode>
                           element. This has <termref def="dt-operand-usage"/>
                           <termref def="dt-transmission"/>. (Note that the
                              <elcode>xsl:catch</elcode> children of <elcode>xsl:try</elcode> are
                           not part of the sequence constructor and therefore not part of this
                           operand.)</p></item><item><p>The <code nobreak="false">select</code> expressions and/or contained 
                          <xtermref spec="XT40" ref="dt-sequence-constructor"/> of the <elcode>xsl:catch</elcode>
                           child elements. These form a <termref def="dt-choice-operand-group"/>
                           with <termref def="dt-operand-usage"/>
                           <termref def="dt-transmission"/>.</p></item></olist><note><p>The overall effect of these rules is that either the
                           <elcode>xsl:try</elcode> branch or the <elcode>xsl:catch</elcode> branch
                        may consume the streamed input, but not both. If there is more than one
                           <elcode>xsl:catch</elcode> branch then they may all consume the input,
                        since only one of these branches can be evaluated.</p></note></div3><div3 id="streamability-xsl-value-of"><head>Streamability of <elcode>xsl:value-of</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:value-of</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref> are as follows:</p><olist><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-absorption"/>)</p></item><item><p>The <code nobreak="false">separator</code> attribute value template (usage <termref def="dt-absorption"/>)</p></item><item><p>The contained 
                          <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage <termref def="dt-absorption"/>).</p></item></olist></div3><div3 id="streamability-xsl-variable"><head>Streamability of <elcode>xsl:variable</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                        <elcode>xsl:variable</elcode> follow the <termref def="dt-general-streamability-rules"/>. The <termref def="dt-operand-role">operand roles</termref> and their <termref def="dt-operand-usage">usages</termref>
                     depend on the <code nobreak="false">as</code> attribute,
                      as follows:</p><olist><item><p>If there is an <code nobreak="false">as</code> attribute, then:</p><olist><item><p>The <code nobreak="false">select</code> expression (with <termref def="dt-type-determined-usage"/> based on the <code nobreak="false">as</code>
                                 attribute).</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (with
                                    <termref def="dt-type-determined-usage"/> based on the
                                    <code nobreak="false">as</code> attribute).</p></item></olist></item><item><p>If there is no <code nobreak="false">as</code> attribute,
                           then:</p><olist><item><p>The <code nobreak="false">select</code> expression (usage <termref def="dt-navigation"/>).</p></item><item><p>The contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> (usage
                                    <termref def="dt-absorption"/>).</p></item></olist></item></olist><note><p>The effect of the initialization expression having usage <termref def="dt-navigation"/> is that it is not possible in streamable constructs
                        to bind a variable to a node in a streamed document.</p></note></div3><div3 id="streamability-xsl-where-populated"><head>Streamability of <elcode>xsl:where-populated</elcode></head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of an
                        <elcode>xsl:where-populated</elcode> instruction are the <termref def="dt-posture"/> and <termref def="dt-sweep"/> 
                    of the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/>.</p></div3></div2><div2 id="classifying-vts"><head>Classifying Value Templates</head><p>A <xtermref spec="XT40" ref="dt-value-template">value template</xtermref> 
                 (that is, an <xtermref spec="XT40" ref="dt-attribute-value-template"/> 
                 or <xtermref spec="XT40" ref="dt-text-value-template"/>)
                  is a <termref def="dt-construct"/> whose operands are the expressions contained
                  within curly brackets. The required type for this operand role is
                     <code nobreak="false">xs:string</code> and the <termref def="dt-operand-usage">usage</termref>
                  is <termref def="dt-absorption"/>.</p><p>The <termref def="dt-sweep"/> and <termref def="dt-posture"/> of a value template
                  are determined using the general rules in <specref ref="general-streamability-rules"/>.</p><p>If there are no expressions contained within curly brackets, the value template is
                     <termref def="dt-motionless"/>.</p></div2><div2 id="classifying-expressions"><head>Classifying Expressions</head><p>XPath expressions are classified using the rules in this section.</p><p>In the analysis that follows, <xtermref spec="XT40" ref="dt-expression">expressions</xtermref>
                  are classified according to the most specific production rule that they match for
                  which there is an entry in this section. A production <var>P</var> is considered
                  more specific than a production <var>Q</var> (<var>Q</var> ≠ <var>P</var>)
                  if every expression that matches <var>P</var> also matches <var>Q</var>. For
                  example:</p><ulist><item><p>The expression <code nobreak="false">3</code> satisfies the productions
                           <code nobreak="false">NumericLiteral</code>, <code nobreak="false">Literal</code>, and
                           <code nobreak="false">ArithmeticExpression</code>; the most specific of these for which
                        there is an entry in this section is <code nobreak="false">Literal</code>.</p></item><item><p>The expression <code nobreak="false">text()</code> (appearing as an expression) is a
                           <code nobreak="false">TextTest</code>, and therefore a <code nobreak="false">KindTest</code>, which is
                        itself a <code nobreak="false">NodeTest</code>, and therefore an <code nobreak="false">AxisStep</code> with
                        a defaulted <code nobreak="false">ForwardAxis</code>. The most specific of these for which
                        there is an entry in this section is <code nobreak="false">AxisStep</code>. Although the
                        expression is also a <code nobreak="false">RelativePathExpr</code>, that production is less
                        specific than <code nobreak="false">AxisStep</code> so its rules do not apply.</p></item><item><p>The expression <code nobreak="false">section/title</code> is a
                        <code nobreak="false">RelativePathExpr</code>, for which there is an entry in this section.
                        Although the expression is also a <code nobreak="false">PathExpr</code>, that production is
                        less specific than <code nobreak="false">RelativePathExpr</code> so its rules do not
                        apply.</p></item></ulist><p>The production rules for different kinds of expression are listed (with their
                  names and numbers) in the order in which they appear in Appendix A.1 of the XPath
                  3.0 specification; rules are also given for
                  new constructs introduced by XPath 3.1. Where two
                  numbers are given, they are the production rule numbers in XPath 3.0 and XPath 3.1 respectively;
                  where there is a single number, it is the production rule number in XPath 3.1.</p><p>Many expressions can be analyzed using the <termref def="dt-general-streamability-rules"/>. These are indicated in the table below
                  by means of a simple proforma in which the <termref def="dt-operand-role">operand
                     roles</termref> are represented by a short code (A = <termref def="dt-absorption"/>, I = <termref def="dt-inspection"/>, T = <termref def="dt-transmission"/>, N = <termref def="dt-navigation"/>). For example the
                  proforma <code nobreak="false">A + A</code> indicates that for an arithmetic expression, both
                  operands have <termref def="dt-operand-usage"/>
                  <termref def="dt-absorption"/>, while <code nobreak="false">I or I</code> indicates that for an
                     <code nobreak="false">or</code> expression, both operands have <termref def="dt-operand-usage"/>
                  <termref def="dt-inspection"/>. For expressions where further explanation is
                  needed, the table contains a link to the relevant section.</p><table class="data"><caption>Operand Roles for XPath Expressions</caption><thead><tr><th rowspan="1" colspan="1">Construct</th><th rowspan="1" colspan="1">Proforma or Reference to Detailed Rules</th><th rowspan="1" colspan="1">Further Information</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">Expr</td><td rowspan="1" colspan="1"><code nobreak="false">T, T</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">ForExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-for-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">LetExpr</td><td rowspan="1" colspan="1"><code nobreak="false">let $var := N return T</code></td><td rowspan="1" colspan="1">Binding of variables to streamed nodes is not allowed.</td></tr><tr><td rowspan="1" colspan="1">QuantifiedExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-quantified-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">IfExpr</td><td rowspan="1" colspan="1"><code nobreak="false">if (I) then T else
                           T</code></td><td rowspan="1" colspan="1">The then-clause and else-clause form a <termref def="dt-choice-operand-group"/> with usage <termref def="dt-transmission"/></td></tr><tr><td rowspan="1" colspan="1">OrExpr</td><td rowspan="1" colspan="1"><code nobreak="false">I or I</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">AndExpr</td><td rowspan="1" colspan="1"><code nobreak="false">I and I</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">StringConcatExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A || A</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">RangeExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A to A</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">AdditiveExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A + A</code>, <code nobreak="false">A - A</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">MultiplicativeExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A * A</code>, <code nobreak="false">A div A</code>, etc.</td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">UnionExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-union-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">IntersectExceptExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-union-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">InstanceOfExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-instance-of-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">TreatExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-treat-as-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">CastableExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A castable as TYPE</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">CastExpr</td><td rowspan="1" colspan="1"><code nobreak="false">A cast as TYPE</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">UnaryExpr</td><td rowspan="1" colspan="1"><code nobreak="false">+A</code>, <code nobreak="false">-A</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">GeneralComp</td><td rowspan="1" colspan="1"><code nobreak="false">A = A</code>, <code nobreak="false">A &lt; A</code>, <code nobreak="false">A != A</code>,
                           etc.</td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">ValueComp</td><td rowspan="1" colspan="1"><code nobreak="false">A eq A</code>, <code nobreak="false">A lt A</code>, <code nobreak="false">A ne A</code>, etc.</td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">NodeComp</td><td rowspan="1" colspan="1"><code nobreak="false">I is I</code>, <code nobreak="false">I &lt;&lt;
                              I</code>, <code nobreak="false">I &gt;&gt; I</code></td><td rowspan="1" colspan="1">See Note 1 below</td></tr><tr><td rowspan="1" colspan="1">SimpleMapExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-simple-mapping-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">PathExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-path-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">RelativePathExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-path-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">AxisStep</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-axis-steps"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">ForwardStep, ReverseStep</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-axis-steps"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">PostfixExpr: Filter Expression</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-filter-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">PostfixExpr: Dynamic Function Call</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-dynamic-function-calls"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">Literal</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">There are no operands, so the construct is <termref def="dt-grounded"/>
                           and <termref def="dt-motionless"/></td></tr><tr><td rowspan="1" colspan="1">VarRef</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-variable-references"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="2" colspan="1">ParenthesizedExpr</td><td rowspan="1" colspan="1"><code nobreak="false">(T)</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">()</code></td><td rowspan="1" colspan="1">There are no operands, so the construct is <termref def="dt-grounded"/>
                           and <termref def="dt-motionless"/></td></tr><tr><td rowspan="1" colspan="1">ContextItemExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-context-item-expression"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">FunctionCall</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-function-calls"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">NamedFunctionRef</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-named-function-ref"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">InlineFunctionExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-inline-functions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">MapConstructor</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-map-constructors"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">Lookup (Postfix and Unary)</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-lookup-expressions"/></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">ArrowExpr</td><td rowspan="1" colspan="1">See <specref ref="streamability-of-function-calls"/>
                           and <specref ref="streamability-of-dynamic-function-calls"/>: 
                           the rules for <code nobreak="false">X =&gt; F(Y, Z)</code> are the same as the rules for <code nobreak="false">F(X, Y, Z)</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">SquareArrayConstructor</td><td rowspan="1" colspan="1"><code nobreak="false">[ N, N, ... ]</code></td><td rowspan="1" colspan="1"/></tr><tr><td rowspan="1" colspan="1">CurlyArrayConstructor</td><td rowspan="1" colspan="1"><code nobreak="false">array { N, N, ... }</code></td><td rowspan="1" colspan="1"/></tr></tbody></table><note><olist><item><p> The operators <code nobreak="false">is</code>, <code nobreak="false">&lt;&lt;</code>, and
                              <code nobreak="false">&gt;&gt;</code> apply to streamed nodes just as to any other
                           nodes, though there are few practical situations where they will be
                           useful. A streamed document conforms to the rules of the XDM data model,
                           and its nodes are therefore distinct and ordered. They follow the usual
                           rules, for example that a parent node precedes its children in document
                           order. Expressions such as <code nobreak="false">.. is parent::X</code> or
                              <code nobreak="false">ancestor::x[1] &lt;&lt; ancestor::y[1]</code> are therefore
                           perfectly meaningful. The usefulness of the operators is limited by the
                           fact that variables cannot be bound to nodes in a streamed document. It
                           is permitted, though perhaps not useful, for one of the operands to be
                              <termref def="dt-consuming"/>: one can write <code nobreak="false">. &lt;&lt;
                              child::x</code>, and the resulting expression is (by applying the
                           general rules) <termref def="dt-consuming"/> and grounded.</p><p>The restriction that variables cannot be bound to streamed nodes prevents
                           writing of expressions such as <code nobreak="false">let $x := . return
                              descendant::x[ancestor::y[1] is $x]</code>. As a workaround, the
                           intended effect can be achieved by comparing node identity using the
                              <xfunction>generate-id</xfunction> function: <code nobreak="false">let $x :=
                              generate-id(.) return descendant::x[generate-id(ancestor::y[1]) =
                              $x]</code></p></item></olist></note><div3 id="streamability-of-for-expressions"><head>Streamability of <code nobreak="false">for</code> Expressions</head><p>Writing the expression as <code nobreak="false">for $v in S return R</code>, the two operand
                     roles are <var>S</var> and <var>R</var>.</p><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> are determined by
                     the first of the following that applies:</p><olist><item><p>If <var>S</var> is not <termref def="dt-grounded"/>, then <termref def="dt-roaming"/>
                           and <termref def="dt-free-ranging"/>.</p></item><item><p>Otherwise, the <termref def="dt-general-streamability-rules"/> apply. The
                           operand roles are:</p><olist><item><p>The <code nobreak="false">in</code> expression (<code nobreak="false">S</code>). This has <termref def="dt-operand-usage">usage</termref>
                                 <termref def="dt-navigation"/>.</p></item><item><p>The <code nobreak="false">return</code> expression (<code nobreak="false">R</code>). This is a
                                    <termref def="dt-higher-order-operand"/> with <termref def="dt-operand-usage">usage</termref>
                                 <termref def="dt-transmission"/>.</p></item></olist></item></olist><note><p>Expressions of the form <code nobreak="false">for $i in 1 to 3 return $i*2</code>, where
                        there is no reference to a streamed node, are clearly streamable.</p><p>The <code nobreak="false">in</code> expression can also be <termref def="dt-consuming"/>,
                        for example <code nobreak="false">for $e in copy-of(emp) return $e/salary</code>.</p><p>The rule that <var>S</var> must be grounded
                        prevents the variable being bound to a node in a streamed document. This
                        disallows expressions of the form <code nobreak="false">for $x in child::section return
                           $x/para</code>, because this requires data flow analysis (tracing from
                        the binding of a variable to its usages), rather than purely syntactic
                        analysis. Some implementations may be able to stream such constructs.</p><p>The fact that the return clause is a higher-order operand prevents it from
                        being a <termref def="dt-consuming"/> expression, for example <code nobreak="false">for $i
                           in 1 to 3 return salary</code>. Use of a motionless expression that
                        accesses streamed nodes is however allowed, for example <code nobreak="false">for $i in 1 to
                           3 return name(ancestor::x[$i])</code>.</p></note></div3><div3 id="streamability-of-quantified-expressions"><head>Streamability of Quantified Expressions</head><p>An expression with multiple in-clauses is first rewritten using nested
                     quantified expressions: for example <code nobreak="false">some $i in X, $j in Y satisfies $i eq
                        $j</code> can be rewritten as <code nobreak="false">some $i in X satisfies (some $j in Y
                        satisfies $i eq $j)</code>. The analysis therefore only needs to consider
                     expressions with a single in-clause.</p><p>Writing such an expression as <code nobreak="false">some|every $v in S satisfies C</code>, the
                     two operand roles are <var>S</var> and <var>C</var>.</p><p>The <termref def="dt-general-streamability-rules"/> apply. The <termref def="dt-operand-role">operand roles</termref> are:</p><olist><item><p>The <code nobreak="false">in</code> expression (<var>S</var>). This has usage <termref def="dt-navigation"/>.</p></item><item><p>The <code nobreak="false">satisfies</code> expression (<var>C</var>). This is a <termref def="dt-higher-order-operand"/> with usage <termref def="dt-inspection"/>.</p></item></olist><note><p>Expressions of the form some <code nobreak="false">$i in 1 to 3 satisfies $i lt 2</code>,
                        where there is no reference to a streamed node, are clearly streamable. </p><p>The expression <var>S</var> can be <termref def="dt-consuming"/>, so long as
                        it is grounded: for example <code nobreak="false">some $e in emp/salary/number(.) satisfies
                           $e gt 10000</code>. </p><p>The rule that <var>S</var> has usage <termref def="dt-navigation"/> prevents
                        the variable being bound to a node in a streamed document. This disallows
                        expressions of the form <code nobreak="false">some $x in child::section satisfies
                           has-children($x)</code>, because this requires data flow analysis
                        (tracing from the binding of a variable to its usages), rather than purely
                        syntactic analysis. Some implementations may be able to stream such
                        constructs. </p><p>The fact that <var>C</var> is a higher-order operand prevents it from being
                        a <termref def="dt-consuming"/> expression: for example <code nobreak="false">some $i in 1
                           to 3 satisfies author[$i] eq "Kay"</code> is not streamable. Use of a
                        motionless expression that accesses streamed nodes is however allowed, for
                        example <code nobreak="false">some $i in 1 to 3 satisfies @grade = $i</code>. </p><p>Quantified expressions that fail the streamability rules can often be
                        rewritten as filter expressions. For example, the expression <code nobreak="false">some $x in
                           child::section satisfies has-children($x)</code> can be rewritten as
                           <code nobreak="false">exists(child::section[has-children(.)])</code>, which is grounded
                        and <termref def="dt-consuming"/>. </p></note></div3><div3 id="streamability-of-if-expressions"><head>Streamability of <code nobreak="false">if</code> expressions</head><p>Writing the expression as <code nobreak="false">if (C) then T else E</code>, there are three
                     operand roles: <var>C</var>, <var>T</var>, and <var>E</var>. The <termref def="dt-operand-usage">usage</termref> of <var>C</var> is <termref def="dt-inspection"/>, while the <termref def="dt-operand-usage">usage</termref> of <var>T</var> and <var>E</var> is <termref def="dt-transmission"/>. Operands <var>T</var> and <var>E</var> form a
                        <termref def="dt-choice-operand-group"/>, meaning that they can both consume
                     the input stream, provided they have consistent <termref def="dt-posture"/>.
                     The <termref def="dt-general-streamability-rules"/> apply.</p></div3><div3 id="streamability-of-union-expressions"><head>Streamability of <code nobreak="false">union</code>, <code nobreak="false">intersect</code>, and
                        <code nobreak="false">except</code> Expressions</head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> are the first of
                     the following that applies:</p><olist><item><p>If either of the two operands is <termref def="dt-free-ranging"/>, then
                              <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>
                           (Example: <code nobreak="false">. | following-sibling::*</code>).</p></item><item><p>If either of the two operands is <termref def="dt-grounded"/> and
                              <termref def="dt-motionless"/>, then the <termref def="dt-posture"/>
                           and <termref def="dt-sweep"/> of the other operand (Example: <code nobreak="false">. |
                              doc('abc.com')//x</code>)</p></item><item><p>If both operands are <termref def="dt-climbing"/>, then <termref def="dt-climbing"/> and the
                           wider of the sweeps of the two operands (Example: <code nobreak="false">parent::A | */ancestor::B</code>).</p></item><item><p>If the left-hand operand is <termref def="dt-striding"/> or <termref def="dt-crawling"/> and the right-hand operand is also
                                 <termref def="dt-striding"/> or <termref def="dt-crawling"/>, then <termref def="dt-crawling"/> and the wider of the
                           sweeps of the two operands (Example: <code nobreak="false">* | */*</code>).</p></item><item><p>Otherwise, <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/> (Example: <code nobreak="false">child::div |
                              parent::div</code>).</p></item></olist><note><p>Essentially the principle is that if both operands are streamable, then the
                        result is streamable (this assumes an evaluation strategy where both
                        operands are evaluated during the same pass of the streamed input document,
                        and the results merged). But there are caveats because of the need for
                        static streamability analysis of the result. This prevents constructs such
                        as <code nobreak="false">.. | *</code> that have heterogeneous <termref def="dt-posture"/>.</p><p>Where the two operands are both <termref def="dt-striding"/>, there are
                        cases where an implementation could determine that the result is also
                           <termref def="dt-striding"/>: for example <code nobreak="false">(author | editor)</code>.
                        In general, however, the combination of two striding operands may produce a
                        sequence of nodes that have nested subtrees (consider <code nobreak="false">author | author/name</code>),
                        so the result is classified as <termref def="dt-crawling"/>.</p><p>The expression <code nobreak="false">(author | editor)</code>, although it is not <termref def="dt-striding"/>, can be rewritten in the form <code nobreak="false">*[self::author or
                           self::editor]</code>, which is <termref def="dt-striding"/>.</p></note></div3><div3 id="streamability-of-instance-of-expressions"><head>Streamability of <code nobreak="false">instance of</code> Expressions</head><p>For an expression of the form <var>X</var> instance of <var>ST</var> (where
                        <var>X</var> is an expression and <var>ST</var> is a
                     <xtermref spec="XT40" ref="dt-sequence-type"/>), 
                     the <termref def="dt-posture"/> and <termref def="dt-sweep"/> are determined by the <termref def="dt-general-streamability-rules"/>. There is a single operand
                        <var>X</var>, whose <termref def="dt-operand-usage"/> is as follows:</p><olist><item><p>If the <code nobreak="false">ItemType</code> of <var>ST</var> is a
                              <code nobreak="false">DocumentTest</code>, optionally parenthesized, that contains an
                              <code nobreak="false">ElementTest</code> or <code nobreak="false">SchemaElementTest</code> then
                           absorption</p></item><item><p>Otherwise, inspection.</p></item></olist><note><p>In general, it is possible to determine whether a node matches an
                           <code nobreak="false">ItemType</code> without consuming the node. For example it can be
                        established whether an element matches the test <code nobreak="false">element(para)</code>
                        when positioned at the start tag.</p><p>An <code nobreak="false">ItemType</code> of the form <code nobreak="false">document-node(element(X))</code>
                        is an exception to this rule because it matches a document node only if it
                        has exactly one element node child, and this cannot be determined without
                        consuming the document. </p><p>A processor may have knowledge that the document node cannot contain
                        multiple element nodes, for example because it knows that the source of the
                        streamed document is an XML parser that is not capable of generating such a
                        stream. In such cases the processor may make a different assessment of the
                        streamability of this construct. This comes under the general provision that
                        a processor is always at liberty to use streaming even when the stylesheet
                        is not guaranteed streamable. </p></note><note><p>As with other constructs that are evaluated with inspection usage, for
                        example the <xfunction>name</xfunction> function or access to an attribute
                        node, evaluation of a construct such as <code nobreak="false">$X instance of
                           schema-element(E)</code> as true or false may be invalidated if reading
                        of the input stream subsequently fails. Dynamic errors during streamed
                        processing of an input document invalidate all output generated prior to the
                        failure, and this case is no different. </p></note><note><p>Given an expression such as <code nobreak="false">child::* instance of element(E)*</code>,
                        the expression as a whole is <termref def="dt-consuming"/> and grounded. By
                        contrast, the expression <code nobreak="false">. instance of element(E)*</code> is
                        motionless and grounded. This can be verified by applying the general
                        streamability rules to these cases. </p></note></div3><div3 id="streamability-of-treat-as-expressions"><head>Streamability of <code nobreak="false">treat as</code> Expressions</head><p/><p>For an expression of the form <var>X</var> treat as <var>ST</var> (where
                     <var>X</var> is an expression and <var>ST</var> is a
                     <xtermref spec="XT40" ref="dt-sequence-type"/>), 
                     the <termref def="dt-posture"/> and <termref def="dt-sweep"/> are determined as follows:  </p><olist><item><p>If the <code nobreak="false">ItemType</code> of <var>ST</var> is a
                           <code nobreak="false">DocumentTest</code>, optionally parenthesized, that contains an
                           <code nobreak="false">ElementTest</code> or <code nobreak="false">SchemaElementTest</code> then
                           <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>Otherwise, the <termref def="dt-general-streamability-rules"/> apply. There is a single operand
                           <var>X</var>, whose <termref def="dt-operand-usage"/> is <termref def="dt-transmission"/>.</p></item></olist><note><p>See the notes in <specref ref="streamability-of-instance-of-expressions"/> for
                  a discussion of the streamability difficulties associated with <code nobreak="false">document-node()</code> tests.</p></note></div3><div3 id="streamability-of-simple-mapping-expressions"><head>Streamability of Simple Mapping Expressions</head><p>The mapping operator <code nobreak="false">!</code> is treated as a left-associative binary
                     operator, so the expression <code nobreak="false">a!b!c</code> is processed as
                        <code nobreak="false">(a!b)!c</code>.</p><p>The <termref def="dt-posture"/> of the expression is
                     the <termref def="dt-posture"/> of the right-hand operand, assessed with a
                        <termref def="dt-context-posture"/> and
                     type set to the <termref def="dt-posture"/> and type of the left-hand operand.</p><p>The <termref def="dt-sweep"/> of the expression is
                     the wider of the <termref def="dt-sweep">sweeps</termref> of the two
                     operands.</p></div3><div3 id="streamability-of-path-expressions"><head>Streamability of Path Expressions</head><p>The streamability analysis applies after the expansion of the <code nobreak="false">//</code>
                     pseudo-operator to <code nobreak="false">/descendant-or-self::node()/</code>, and after
                     expanding <code nobreak="false">..</code> to <code nobreak="false">parent::node()</code>, <code nobreak="false">@X</code> to
                        <code nobreak="false">attribute::X</code>, and an omitted axis to the default axis for the node kind.</p><p>Following the rules in XPath, a leading <code nobreak="false">"/"</code> is converted to
                        <code nobreak="false">(root(self::node()) treat as document-node())/</code> (with the final
                        <code nobreak="false">"/"</code> omitted for the expression <code nobreak="false">"/"</code> on its own).
                     This is followed by a rewrite of the call on <xfunction>root</xfunction>, as
                     described in <specref ref="streamability-fn-root"/>.</p><note><p>Taken together, these rewrites have the effect that a path expression such
                        as <code nobreak="false">//a</code> is streamable only if the statically determined context
                        item type is <code nobreak="false">document-node()</code>, which will be the case for
                        example immediately within <elcode>xsl:source-document</elcode>, or in a template
                        rule with <code nobreak="false">match="/"</code>.</p></note><p>A <code nobreak="false">RelativePathExpr</code> with more than two operands (such as
                        <code nobreak="false">a/b/c</code>) is taken as a tree of binary expressions (that is,
                        <code nobreak="false">(a/b)/c</code>).</p><p>The <termref def="dt-sweep"/> of a relative path expression is the wider
                        <termref def="dt-sweep"/> of the two operands, where the ordering of
                     increasing width is <termref def="dt-motionless"/>, <termref def="dt-consuming"/>, <termref def="dt-free-ranging"/>.</p><note><p>Examples:</p><ulist><item><p>The <termref def="dt-sweep"/> of <code nobreak="false">a/@code</code> is <termref def="dt-consuming"/> (the wider of <termref def="dt-consuming"/>
                              and <termref def="dt-motionless"/>).</p></item><item><p>The <termref def="dt-sweep"/> of <code nobreak="false">a/descendant::b</code> is
                                 <termref def="dt-consuming"/> (the wider of <termref def="dt-consuming"/> and <termref def="dt-consuming"/>).</p></item><item><p>The <termref def="dt-sweep"/> of <code nobreak="false">./@code</code> is <termref def="dt-motionless"/> (the wider of <termref def="dt-motionless"/>
                              and <termref def="dt-motionless"/>).</p></item><item><p>The <termref def="dt-sweep"/> of <code nobreak="false">./a</code> is <termref def="dt-consuming"/> (the wider of <termref def="dt-motionless"/>
                              and <termref def="dt-consuming"/>).</p></item><item><p>The <termref def="dt-sweep"/> of <code nobreak="false">a/following::b</code> is
                                 <termref def="dt-free-ranging"/> (the wider of <termref def="dt-consuming"/> and <termref def="dt-free-ranging"/>).</p></item><item><p>The <termref def="dt-sweep"/> of <code nobreak="false">./.</code> is <termref def="dt-motionless"/> (the wider of <termref def="dt-motionless"/>
                              and <termref def="dt-motionless"/>).</p></item></ulist></note><p>The <termref def="dt-posture"/> of a relative path
                     expression is assessed in two phases, as follows:</p><olist><item><p>First, the provisional <termref def="dt-posture"/> is determined as
                           follows: The provisional <termref def="dt-posture"/> of the expression is
                           the <termref def="dt-posture"/> of the right-hand operand, assessed with
                           a <termref def="dt-context-posture"/>
                           and type set to the <termref def="dt-posture"/> and type of the left-hand operand; and the
                           provisional sweep is the wider of the sweeps of the two operands.</p></item><item><p>If the provisional <termref def="dt-posture"/> is <termref def="dt-roaming"/>, then it is
                           reassessed as follows:</p><olist><item><p><termdef id="dt-scanning-expression" term="scanning expression">A 
                                 <code nobreak="false">RelativePathExpr</code> is a <term>scanning expression</term>
                              if and only if it is syntactically equivalent to some <termref def="dt-motionless"/>
                              <xtermref spec="XT40" ref="dt-pattern"/>.</termdef></p><note><p>This means that a <code nobreak="false">RelativePathExpr</code>
                              is a <term>scanning expression</term> if it conforms to the grammar for a <code nobreak="false">RelativePathExprP</code>
                              in the grammar for patterns (see <xspecref spec="XT40" ref="pattern-syntax"/>),
                              and if, when considered as a pattern, the pattern is motionless according to the
                              rules in <specref ref="classifying-patterns"/>.</p><p>In practice, the test as to whether the construct is equivalent to a pattern is likely
                              to be made by examining the structure of the expression tree, rather than by re-parsing the
                              lexical form of the expression against the grammar for patterns; but the outcome is the same.</p></note></item><item><p>If the expression is a <term>scanning expression</term> then:</p><olist><item><p>If the static type of the expression contains
                                          <code nobreak="false">U{element}</code> then its <termref def="dt-posture"/> is <termref def="dt-crawling"/>.</p></item><item><p>Otherwise, its <termref def="dt-posture"/> is <termref def="dt-striding"/></p></item></olist></item></olist></item><item><p>Otherwise (if the provisional <termref def="dt-posture"/> is not <termref def="dt-roaming"/>, or
                           the expression is not a <term>scanning expression</term>), the <termref def="dt-posture"/> of the expression is the provisional <termref def="dt-posture"/>.</p></item></olist><note><p>The special rules for scanning expressions are designed to ensure
                     that expressions such as <code nobreak="false">//section/head</code> are streamable. The problem
                     with such an expression is that it is
                     possible to have two nested sections <var>A</var> and <var>B</var>, where <var>A</var>
                     is the parent of <var>B</var> and thus precedes <var>B</var> in document order,
                     but where there are children of <var>A</var> that come <emph>after</emph>
                     children of <var>B</var> in document order. This means that a nested-loop
                     strategy for the evaluation of <code nobreak="false">/descendant::section/child::head</code>
                     is not guaranteed to deliver nodes in document order without a sort, and is therefore not
                     a viable strategy for streaming.</p><p>However, there is a different strategy for evaluating such an expression,
                     which is in effect to rewrite the expression as <code nobreak="false">/descendant::head[parent::section]</code>;
                     specifically, it is possible to scan all descendants in document order, looking for a <code nobreak="false">head</code>
                     element that has a <code nobreak="false">section</code> parent. Hence the term <term>scanning expressions</term>.</p><p>The expressions that qualify as scanning expressions are paths that can be evaluated
                        by scanning all descendants and testing each one (independently) to see whether the elements
                        on its ancestor axis match the specified path. The subset of expressions that qualify 
                        as scanning expressions is therefore the same as the subset that qualify as motionless patterns.</p><p>Scanning expressions cannot use positional predicates: for example <code nobreak="false">//section/head[1]</code>
                        is not recognized as a scanning expression because this would require information
                        about a streamed node (specifically, about its preceding siblings) that is not retained during streaming.
                        </p></note><note><p>Perhaps surprisingly, the expression <code nobreak="false">.//section/head</code> is not a scanning
                     expression and is therefore not guaranteed streamable. This is because it does not take
                     the syntactic form of a <xtermref spec="XT40" ref="dt-pattern"/>. To make it streamable, it can be rewritten as 
                     <code nobreak="false">descendant::section/head</code> or as <code nobreak="false">self::node()//section/head</code>.</p><p>Similarly, within a streamable stylesheet function whose <termref def="dt-streaming-parameter"/> is
                     <code nobreak="false">$node</code>, the expression <code nobreak="false">$node//section/head</code> is not a scanning 
                     expression. In this case the expression does have the syntactic form of a pattern, but the
                     pattern is not classified as motionless. (See <specref ref="classifying-patterns"/> — a
                     motionless pattern cannot contain a <code nobreak="false">RootedPath</code>.) A workaround in this case
                     is to rewrite the expression as <code nobreak="false">$node/(descendant::section/head)</code>. Assuming that the
                        function in question declares <code nobreak="false">streamability="absorbing"</code>, the analysis here is
                     that the left-hand operand (<code nobreak="false">$node</code>) is striding and consuming, while the right hand 
                     operand (<code nobreak="false">descendant::section/head</code>) is crawling and consuming (because it is a
                     scanning expression). The expression as a whole is therefore crawling and consuming.</p><p>These are cases where an implementation might reasonably choose to relax the rules,
                     insofar as this is permitted by <specref ref="streamability-guarantees"/>.</p></note><note><p>Examples:</p><p>In each of the following cases, assume that the <termref def="dt-context-posture"/> is striding.</p><ulist><item><p>The <termref def="dt-posture"/> of the expression <code nobreak="false">a/b/c</code>
                              is striding, because (under the rules for AxisStep [38]) a child axis
                              step evaluated with striding context <termref def="dt-posture"/>
                              creates a new striding posture.</p></item><item><p>The posture of the expression <code nobreak="false">a/descendant::c</code> is
                              crawling, because a descendant axis step evaluated with striding
                              context posture creates a new crawling posture.</p></item><item><p>The posture of the expression
                                 <code nobreak="false">../@status</code> is striding, because a parent axis step
                              evaluated with striding context posture creates a new climbing
                              posture, and an attribute axis step evaluated with climbing context
                              posture creates a new striding posture.</p></item><item><p>The posture of the expression
                                 <code nobreak="false">copy-of(.)//a/following-sibling::*</code> is grounded,
                              because the <function>copy-of</function> evaluated with striding
                              posture creates a grounded posture, and all subsequent axis steps
                              leave this posture unchanged.</p></item><item><p>The expression <code nobreak="false">section//head</code>
                              expands to
                                 <code nobreak="false">(section/descendant-or-self::node())/child::head</code>. The
                              posture of the left-hand operand
                                 <code nobreak="false">section/descendant-or-self::node()</code> is crawling,
                              because a descendant axis step evaluated with striding context posture
                              creates a new crawling posture. The provisional posture of the
                              expression as a whole is therefore <termref def="dt-roaming"/>, because a child axis step
                              evaluated with crawling context posture gives a resulting roaming posture. However, the expression
                              is a scanning expression (both <code nobreak="false">section//head</code> and its expansion are
                              motionless patterns), so the expression as a whole has
                              crawling posture. </p></item><item><p>The expression <code nobreak="false">section//head[1]</code> is
                              free-ranging: unlike the previous example, it contains a positional
                              predicate, which means that the operands do not satisfy the rules for
                              scanning expressions. </p></item></ulist></note></div3><div3 id="streamability-of-axis-steps"><head>Streamability of Axis Steps</head><p>The <termref def="dt-sweep"/> and <termref def="dt-posture"/> of an AxisStep
                        <var>S</var> are determined by the first of the following rules that
                     applies:</p><olist><item><p>If the <termref def="dt-context-posture"/> is <termref def="dt-grounded"/>, then the sweep is
                              <termref def="dt-motionless"/> and the posture is <termref def="dt-grounded"/>;</p></item><item><p>If the <termref def="dt-context-posture"/> is <termref def="dt-roaming"/>, then the sweep is <termref def="dt-free-ranging"/> and the posture is <termref def="dt-roaming"/>;</p></item><item><p>If the statically inferred <termref def="dt-context-item-type"/> is such
                           that the axis will always be empty (for example, applying the child axis
                           to a text node or the parent axis to a document node), or if the <code nobreak="false">NodeTest</code> is one that can never
                              select nodes on the chosen axis (for example, selecting attribute
                              nodes on the child axis), then the sweep is <termref def="dt-motionless"/> and the posture is <termref def="dt-grounded"/>
                           (because the expression is statically known to return an empty
                           sequence);</p></item><item><p>If all the following conditions are satisfied:</p><olist><item><p>The <termref def="dt-context-posture"/> is <termref def="dt-striding"/></p></item><item><p>The axis is <code nobreak="false">descendant</code> or
                                    <code nobreak="false">descendant-or-self</code></p></item><item><p>There is a predicate <var>P</var> in the list of predicates
                                 that satisfies all the following conditions:</p><olist><item><p>The static type of <var>P</var> is a subtype of
                                          <code nobreak="false">U{xs:decimal, xs:double, xs:float}</code></p></item><item><p>The maximum cardinality of <var>P</var> is 1</p></item><item><p>Neither <var>P</var>, nor any operand of <var>P</var>, at any
                                       depth provided it has the AxisStep <var>S</var> as its
                                          <termref def="dt-focus-setting-container"/>, is a context
                                       item expression, an axis expression, or a call on a
                                       focus-dependent function;</p></item></olist></item></olist><p>then <termref def="dt-striding"/> and <termref def="dt-consuming"/></p><note><p>Examples are <code nobreak="false">descendant::section[1]</code>,
                                 <code nobreak="false">descendant::section[$i+1]</code>,
                                 <code nobreak="false">descendant::section[count($x)]</code>. The significance of
                              this rule is that it detects cases where the descendant axis selects a
                              singleton, and where the posture of the result can therefore be
                                 <termref def="dt-striding"/> rather than <termref def="dt-crawling"/>.</p></note></item><item><p>If the list of predicates contains a <code nobreak="false">Predicate</code> that
                           is not <termref def="dt-motionless"/>, then the sweep is <termref def="dt-free-ranging"/> and the posture is <termref def="dt-roaming"/>;</p></item><item><p>Otherwise, the <termref def="dt-sweep"/> and <termref def="dt-posture"/>
                           of the expression are as determined by the table below, based on the
                              <termref def="dt-context-posture"/>, the choice of axis, and the node test. The condition
                           “Selects elements?” is true if the <termref def="dt-utype"/> of
                              <var>S</var> has a non-empty intersection with
                           <var>U{element()}</var>.</p><table class="data"><caption>Streamability of Axis Steps Based on Context Posture</caption><thead><tr><th rowspan="1" colspan="1">Context posture</th><th rowspan="1" colspan="1">Axis</th><th rowspan="1" colspan="1">Selects elements?</th><th rowspan="1" colspan="1">Result posture</th><th rowspan="1" colspan="1">Sweep</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">Grounded</td><td rowspan="1" colspan="1">any</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Grounded</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Climbing</td><td rowspan="1" colspan="1">self, parent, ancestor-or-self, ancestor</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Climbing</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Climbing</td><td rowspan="1" colspan="1">attribute, namespace</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">parent, ancestor-or-self,
                                    ancestor</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Climbing</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">self, attribute, namespace</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">child</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">Consuming</td></tr><tr><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">descendant, descendant-or-self</td><td rowspan="1" colspan="1">Yes</td><td rowspan="1" colspan="1">Crawling</td><td rowspan="1" colspan="1">Consuming</td></tr><tr><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">descendant, descendant-or-self</td><td rowspan="1" colspan="1">No</td><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">Consuming</td></tr><tr><td rowspan="1" colspan="1">Crawling</td><td rowspan="1" colspan="1">parent, ancestor-or-self,
                                    ancestor</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Climbing</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Crawling</td><td rowspan="1" colspan="1">attribute, namespace</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Crawling</td><td rowspan="1" colspan="1">self</td><td rowspan="1" colspan="1">Yes</td><td rowspan="1" colspan="1">Crawling</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td rowspan="1" colspan="1">Crawling</td><td rowspan="1" colspan="1">self</td><td rowspan="1" colspan="1">No</td><td rowspan="1" colspan="1">Striding</td><td rowspan="1" colspan="1">Motionless</td></tr><tr><td colspan="2" rowspan="1">Any other combination</td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">Roaming</td><td rowspan="1" colspan="1">Free-ranging</td></tr></tbody></table></item></olist><note><p>This analysis does not attempt to classify <code nobreak="false">para[title]</code> as a
                           <termref def="dt-consuming"/> expression; an implementation might choose
                        to do so.</p></note></div3><div3 id="streamability-of-filter-expressions"><head>Streamability of Filter Expressions</head><p>For a filter expression <var>F</var> of the form <code nobreak="false">B[P]</code> (where
                        <var>B</var> might itself be a filter expression), the <termref def="dt-posture"/> and <termref def="dt-sweep"/> are the first of the
                     following that applies:</p><olist><item><p>If all the following conditions are satisfied:</p><olist><item><p><var>B</var> is crawling;</p></item><item><p>The static type of <var>P</var> is a subtype of <code nobreak="false">U{xs:decimal,
                                    xs:double, xs:float}</code>;</p></item><item><p>The maximum cardinality of <var>P</var> is 1;</p></item><item><p>Neither <var>P</var>, nor any operand of <var>P</var>, at any depth
                                 provided it has <var>F</var> as its focus-setting container, is a
                                 context item expression, an axis expression, or a call on a
                                 focus-dependent function</p></item></olist><p>then the <termref def="dt-posture"/> is <termref def="dt-striding"/> and
                           the <termref def="dt-sweep"/> is the sweep of <var>B</var>. </p><note><p>This rule captures cases where it can be statically determined that
                              the predicate is a single numeric item and is independent of the focus. In such
                              cases, the filter expression selects at most one node, and the posture
                              can therefore be changed from crawling to striding (if there is only
                              one node, there can be no overlapping trees). Examples of filter
                              expressions that satisfy this test are <code nobreak="false">(//x)[3]</code>,
                                 <code nobreak="false">(//x)[$i+1]</code>, <code nobreak="false">(//x)[index-of($a,
                                 $b)[last()]]</code>. The expression <code nobreak="false">(//x)[1 to 5]</code> does
                              not satisfy the test, because the value of the predicate is not a singleton.</p></note></item><item><p>If <var>P</var> is <termref def="dt-motionless"/>, then the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of <var>B</var>;</p><note><p>This includes the case where <var>B</var> is grounded. The predicate
                                 <var>P</var> is assessed with the posture of <var>B</var> as its
                              context posture, and if this is grounded, then <var>P</var> will
                              almost invariably be motionless, making the filter expression as a
                              whole grounded and motionless. For example if <code nobreak="false">$s</code> is
                              grounded, then <code nobreak="false">$s[child::*]</code> is also grounded. A
                              counter-example is the expression <code nobreak="false">$s[$n = 2]</code> where
                                 <code nobreak="false">$n</code> is a reference to the first argument of a stylesheet function
                              that is <termref def="dt-declared-streamable"/>: here the predicate is
                              not motionless, so the filter expression is roaming and
                              free-ranging.</p></note></item><item><p>Otherwise, <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item></olist><note><p>The first rule allows a construct such as <code nobreak="false">&lt;xsl:apply-templates
                           select="(//title)[1]"/&gt;</code>, where a <termref def="dt-crawling"/>
                        operand would not be guaranteed streamable.</p></note><note><p>This section is not applicable to predicates forming part of an axis step,
                        such as <code nobreak="false">//title[1]</code>, as these are not technically filter
                        expressions. See <specref ref="streamability-of-axis-steps"/>.</p></note></div3><div3 id="streamability-of-dynamic-function-calls"><head>Streamability of Dynamic Function Calls</head><note><p>This section applies to dynamic function calls written using the traditional
                        syntax <code nobreak="false">$F(X, Y, Z)</code> and equally to those using the syntax <code nobreak="false">X =&gt; $F(Y, Z)</code></p></note><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of a dynamic
                     function call such as <code nobreak="false">$F(X, Y)</code> are determined by the <specref ref="general-streamability-rules"/>. The operands and their usages are as
                     follows:</p><olist><item><p>The base expression that computes the function value itself (here
                              <code nobreak="false">$F</code>). This has usage <termref def="dt-inspection"/>.</p></item><item><p>The argument expressions excluding any
                                 <code nobreak="false">?</code> placeholders (here <code nobreak="false">X</code> and
                              <code nobreak="false">Y</code>). These have <termref def="dt-type-determined-usage"/>
                           dependent on ancillary information
                              associated with the <termref def="dt-static-type"/> of the base
                              expression, where available (see <specref ref="determining-static-type"/>). If this information indicates
                              that the base expression is a function with signature
                           <code nobreak="false">fn(A, B, ...) as R</code>, then the first argument
                              <code nobreak="false">X</code> has <termref def="dt-type-determined-usage"/> based on
                           the first argument type <code nobreak="false">A</code>, the second argument
                              <code nobreak="false">Y</code> has <termref def="dt-type-determined-usage"/> based on
                           the second argument type <code nobreak="false">B</code>, and so on. If no function signature is available, then the
                           usage of each of the argument expressions is <termref def="dt-navigation"/>.</p></item></olist><note><p>As explained in <xspecref spec="XT40" ref="function-lookup"/>, use of a dynamic function
                        call where the function value is bound to a focus-dependent function such as
                           <code nobreak="false">name#0</code>, <code nobreak="false">lang#1</code>, or <code nobreak="false">last#0</code> is
                        likely to lead to a dynamic error if the context item is a node in a
                        streamed document, but this does not affect the static streamability
                        analysis.</p></note><note><p>Maps and arrays are functions, and it is possible to look up a value in a map
                     or array using a dynamic function call of the form <code nobreak="false">$map($key)</code> or
                     <code nobreak="false">$array($index)</code>. If it is statically known that the function in question
                     is a map or array, then it is also known that the argument type is <code nobreak="false">xs:anyAtomicType</code>,
                     and that the operand usage is therefore <termref def="dt-absorption"/>. A call that
                     passes a streamed node will therefore be <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.
                     However, if it is not known statically that the function is a map or array, then the expression
                     will generally be <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p><p>This means it is desirable to declare the type of any variable holding a map or array. 
                     If streamable nodes are used to lookup a value in a map or array, then it may be advisable to use
                     the <code nobreak="false">map:get</code> or <code nobreak="false">array:get</code> functions explicitly; or<phrase diff="del" at="2022-01-01">, if XPath 3.1 is available,</phrase>
                     the lookup operator (<code nobreak="false">?</code>).</p></note></div3><div3 id="streamability-of-variable-references"><head>Streamability of Variable References</head><p>For variable references that are bound to the
                        <termref def="dt-streaming-parameter"/> of a <termref def="dt-declared-streamable"/>
                     <xtermref spec="XT40" ref="dt-stylesheet-function"/>, see the rules for the <termref def="dt-streamability-category"/> of the containing function, under <specref ref="streamable-stylesheet-functions"/>.</p><p>In all other cases, variable references are <termref def="dt-grounded"/> and
                        <termref def="dt-motionless"/>.</p></div3><div3 id="streamability-of-context-item-expression"><head>Streamability of the Context Item Expression</head><p>The <termref def="dt-posture"/> of the expression is the <termref def="dt-context-posture"/>, and the <termref def="dt-sweep"/> is <termref def="dt-motionless"/>.</p><note><p>Although <code nobreak="false">.</code> is intrinsically motionless, when used in certain
                        contexts (such as <code nobreak="false">data(.)</code>) the containing expression will be
                           <termref def="dt-consuming"/>. This arises because of the <termref def="dt-operand-usage"/>: the argument to <xfunction>data</xfunction> has
                        usage <termref def="dt-absorption"/>, and the combination of a <termref def="dt-motionless"/> operand with usage <termref def="dt-absorption"/>
                        leads to the containing expression being <termref def="dt-consuming"/>.</p><p>Similarly, if <code nobreak="false">.</code> is used where the <termref def="dt-operand-usage"/> is <termref def="dt-navigation"/>, the
                        containing expression will be <termref def="dt-free-ranging"/>.</p></note></div3><div3 id="streamability-of-function-calls"><head>Streamability of Static Function Calls</head><note><p>This section applies to static function calls written using the traditional
                     syntax <code nobreak="false">F(X, Y, Z)</code> and equally to those using the syntax <code nobreak="false">X =&gt; F(Y, Z)</code></p></note><p>For calls to built-in functions, see <specref ref="classifying-built-in-functions"/>.</p><p>For calls to <xtermref spec="XT40" ref="dt-stylesheet-function">stylesheet functions</xtermref>, see <specref ref="streamable-stylesheet-functions"/>.</p><p>For partial function applications (where one or more of the arguments is
                     supplied as a <code nobreak="false">?</code> placeholder), see the rules at the end of this
                     section.</p><p>For a call to a constructor function, the <specref ref="general-streamability-rules"/> apply. There is a single operand role
                     (the argument to the function), with <termref def="dt-operand-usage"/>
                     <termref def="dt-absorption"/>.</p><p>For a call to an <xtermref spec="XT40" ref="dt-extension-function"/>, the <termref def="dt-posture"/> and <termref def="dt-sweep"/> are <termref def="dt-implementation-defined"/>.</p><p>If the function call is a partial function
                     application (that is, if one or more of the arguments is given as a
                        <code nobreak="false">?</code> placeholder), then:</p><olist><item><p>If the function is focus-dependent and
                              the <termref def="dt-context-posture"/> is not <termref def="dt-grounded"/>, then the function call is <termref def="dt-roaming"/> and
                           <termref def="dt-free-ranging"/>.</p></item><item><p>If the target of the function call is a
                              <xtermref spec="XT40" ref="dt-stylesheet-function"/>
                           that is <termref def="dt-declared-streamable"/>, and if the first argument is actually
                           supplied (that is, this argument is not supplied as a <code nobreak="false">?</code>
                           placeholder), and if the expression
                              that is supplied as the first argument is not <termref def="dt-grounded"/>, then the function call is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item><item><p>If the target is an <xtermref spec="XT40" ref="dt-extension-function"/>, 
                          the <termref def="dt-posture"/> and
                              <termref def="dt-sweep"/> are <termref def="dt-implementation-defined"/>.</p></item><item><p>Otherwise, the <termref def="dt-general-streamability-rules"/> apply.
                              The operands of a partial function
                              application are the expressions actually supplied as arguments to the
                              function, ignoring <code nobreak="false">?</code> place-holders; the corresponding
                                 <termref def="dt-operand-usage"/> is the <termref def="dt-type-determined-usage"/> based on the declared type of that
                              argument.</p></item></olist></div3><div3 id="streamability-of-named-function-ref"><head>Streamability of Named Function References</head><p>Let <var>F</var> be the function to which the <code nobreak="false">NamedFunctionRef</code>
                     refers.</p><p>If <var>F</var> is focus-dependent and the
                           <termref def="dt-context-posture"/> is not <termref def="dt-grounded"/>, then the <code nobreak="false">NamedFunctionRef</code> is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p><p>If <var>F</var> is an <xtermref spec="XT40" ref="dt-extension-function"/>, the <termref def="dt-posture"/> and <termref def="dt-sweep"/> are <termref def="dt-implementation-defined"/>.</p><p>Otherwise, the <code nobreak="false">NamedFunctionRef</code> is <termref def="dt-grounded"/> and
                     <termref def="dt-motionless"/>. </p><note><p>The main intent behind these rules is to ensure that the function item
                        returned by a named function reference does not encapsulate a reference to a
                        streamed node.</p><p>In the case of an expression such as <code nobreak="false">local-name#0</code>,
                        implementations might be able to do better by pre-evaluating the function at
                        the point where the named function reference occurs.</p><p>In the case of extension functions, implementations may be able to
                        distinguish whether the function is focus-dependent, and decide the
                        streamability of the named function reference accordingly.</p></note></div3><div3 id="streamability-of-inline-functions"><head>Streamability of Inline Function Declarations</head><p>An inline function declaration that textually
                     contains a variable reference bound to a <termref def="dt-streaming-parameter"/> (of some containing stylesheet function) is <termref def="dt-roaming"/> and
                        <termref def="dt-free-ranging"/>.</p><p>All other inline function declarations are <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p><note><p>It is not possible to pass a streamed node as an argument to a call to an
                        inline function unless the declared type of the corresponding function
                        parameter causes the node to be atomized: see <specref ref="streamability-of-dynamic-function-calls"/>. The only other way an
                        inline function could access a streamed node is by having the streamed node
                        in its closure, and this is prevented by the rule above.</p></note></div3><div3 id="streamability-of-map-constructors"><head>Streamability of Map Constructors</head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of a map
                     constructor (see <xspecref spec="XP40" ref="id-map-constructors"/>) are the same as the
                        <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the equivalent
                        <elcode>xsl:map</elcode> instruction. The equivalent
                        <elcode>xsl:map</elcode> instruction is formed by creating a sequence of
                        <elcode>xsl:map-entry</elcode> instructions, one for each key/value pair in
                     the map expression, where the key expression becomes the value of
                        <code nobreak="false">xsl:map-entry/@key</code>, and the value expression becomes the value
                     of <code nobreak="false">xsl:map-entry/@select</code>; this sequence of
                        <elcode>xsl:map-entry</elcode> instructions is then wrapped in an
                        <elcode>xsl:map</elcode> parent instruction.</p><p>For example, the map constructor <code nobreak="false">{ 'red': false(),
                        'green': true() }</code> translates to the instruction:</p><eg role="xslt-instruction" xml:space="preserve">
&lt;xsl:map&gt;
  &lt;xsl:map-entry key="'red'" select="false()"/&gt;
  &lt;xsl:map-entry key="'green'" select="true()"/&gt;
&lt;/xsl:map&gt;</eg><p>The rules for the streamability of <elcode>xsl:map</elcode> appear in <specref ref="streamability-xsl-map"/>.</p><p>See also <specref ref="maps-streaming"/>.</p></div3><div3 id="streamability-of-lookup-expressions"><head>Streamability of Lookup Expressions</head><p diff="del" at="2022-01-01">Lookup expressions for maps are defined in XPath 3.1, and are available
                  in XSLT 3.0 whether or not XPath 3.1 is supported. Lookup expressions for arrays are defined in the
                  XPath 3.1 specification (see <xspecref spec="XP40" ref="id-lookup"/>), and are available only in XSLT 3.0
                  processors that provide the XPath 3.1 Feature (see ....).</p><p>For the unary lookup operator, the <termref def="dt-posture"/> and <termref def="dt-sweep"/> 
                     of the expression <code nobreak="false">?X</code> are
                     defined to be the same as the <termref def="dt-posture"/> and <termref def="dt-sweep"/> 
                     of the postfix lookup expression <code nobreak="false">.?X</code>.</p><p>For the postfix lookup expression <code nobreak="false">E?K</code>, the <termref def="dt-general-streamability-rules"/> apply as follows:</p><olist><item><p>In the wildcard form of the expression, <code nobreak="false">E?*</code>, there is only one operand, <code nobreak="false">E</code>.
                     This has <termref def="dt-operand-usage"/> <termref def="dt-inspection"/>.</p></item><item><p>Where the construct <code nobreak="false">K</code> is an NCName, the expression <code nobreak="false">E?NAME</code> is treated as
                        equivalent to <code nobreak="false">E?("NAME")</code>.</p></item><item><p>Where the construct <code nobreak="false">K</code> is an integer, the expression <code nobreak="false">E?N</code> is treated as
                        equivalent to <code nobreak="false">E?(N)</code>.</p></item><item><p>In the general case where <code nobreak="false">K</code> is a parenthesized expression, the lookup expression
                        <code nobreak="false">E?(K)</code> has two operands. The first operand <code nobreak="false">E</code> has <termref def="dt-operand-usage"/> 
                        <termref def="dt-inspection"/>, while the second operand <code nobreak="false">K</code> has <termref def="dt-operand-usage"/>
                        <termref def="dt-absorption"/>.</p></item></olist></div3></div2><div2 id="classifying-built-in-functions"><head>Classifying Calls to Built-In Functions</head><p>This section describes the rules that determine the streamability of calls to
                  built-in functions. These differ from user-written functions because it is known
                  (defined in the specification) how nodes supplied as operands are used. Knowledge
                  of the usage of each operand, together with the <termref def="dt-posture"/> of the
                  actual operands, is in most cases enough to determine the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the function result.</p><p>All the built-in functions are listed below. For most functions, a simple proforma
                  is shown that indicates the operand usage of each argument, using the code (A =
                     <termref def="dt-absorption"/>, I = <termref def="dt-inspection"/>, T =
                     <termref def="dt-transmission"/>, N = <termref def="dt-navigation"/>). So, for
                  example, the entry <code nobreak="false">fn:remove(T, A)</code> means that for the function
                     <xfunction>fn:remove#2</xfunction>, the <termref def="dt-operand-usage"/> of the first
                  argument is <termref def="dt-transmission"/>, and the <termref def="dt-operand-usage"/> of the second argument is <termref def="dt-absorption"/>. By reference to the general rules in <specref ref="general-streamability-rules"/>, this demonstrates that if the <termref def="dt-context-posture"/> is <termref def="dt-striding"/>, the posture and sweep of the expression
                     <code nobreak="false">sum(remove(*,1))</code> will be <code nobreak="false">grounded</code> and
                     <code nobreak="false">consuming</code> respectively. </p><p>For functions that default one of their arguments (typically to the context item),
                  the relevant entry shows the equivalence, and the posture and sweep can in these
                  cases be computed by filling in the default value for the relevant argument.</p><p>Some functions do not follow the general rules, and these are listed with a link
                  to the section where the particular rules for that function are described.</p><?built-in-function-streamability?><div3 id="streamability-fn-accumulator-after"><head>Streamability of the <function>accumulator-after</function> Function</head><p>See also <specref ref="streamability-of-accumulators"/>.</p><p>The <termref def="dt-posture"/> of the function call is in all cases <termref def="dt-grounded"/>.</p><p>The <termref def="dt-sweep"/> is determined by applying the following rules, in
                     order:</p><olist><item><p>If the first argument (the accumulator name) is not <termref def="dt-motionless"/>, the function is <termref def="dt-free-ranging"/>. </p></item><item><p>If the <termref def="dt-context-posture"/> is <termref def="dt-grounded"/>, the function is <termref def="dt-motionless"/>. </p></item><item><p>If the <termref def="dt-context-item-type"/> has an empty intersection
                           with <var>U{document-node(), element()}</var> (that is, if the context
                           item cannot have children), the function is <termref def="dt-motionless"/>. </p></item><item><p>If the function call is contained in the <code nobreak="false">select</code> expression
                           or contained sequence constructor of an
                              <elcode>xsl:accumulator-rule</elcode> specifying
                              <code nobreak="false">phase="start"</code>, then it is <termref def="dt-free-ranging"/>.</p></item><item><p>If the function call is contained in the <code nobreak="false">select</code> expression
                           or contained sequence constructor of an
                              <elcode>xsl:accumulator-rule</elcode> specifying
                              <code nobreak="false">phase="end"</code>, then it is <termref def="dt-motionless"/>.</p></item><item><p>If no enclosing node of the function
                              call is part of a <xtermref spec="XT40" ref="dt-sequence-constructor"/>, then it is
                                 <termref def="dt-free-ranging"/>. For this purpose, the
                                 <term>enclosing nodes</term> of a function call are the attribute
                              or text node that immediately contains the XPath expression in which
                              the function call appears, and its ancestors.
                        </p></item><item><p>If the <termref def="dt-focus-setting-container"/> of the function call
                           is different from the <termref def="dt-focus-setting-container"/> of the
                           innermost containing <xtermref spec="XT40" ref="dt-instruction"/>, then the function
                           is <termref def="dt-free-ranging"/>. </p></item><item><p>If no enclosing node <var>N</var> of
                              the function call has a preceding sibling node <var>P</var> such that
                              (a) <var>N</var> and <var>P</var> are part of the same <xtermref spec="XT40" ref="dt-sequence-constructor"/>, and (b) the <termref def="dt-sweep"/> of <var>P</var> is <termref def="dt-consuming"/>,
                              then the function call is <termref def="dt-consuming"/>. (The term
                                 <term>enclosing node</term> is defined above.)</p></item><item><p>Otherwise, the function call is <termref def="dt-motionless"/>.</p></item></olist><note><p>The following notes apply to the above rules with matching numbers:</p><olist><item><p>This rule prevents the accumulator name being computed by reading the
                              streamed source document. This is disallowed primarily because there
                              is no conceivable use case for doing it.</p></item><item><p>If the context posture is grounded, then the target of the accumulator
                              is not a streamed node, so no streaming restrictions apply.</p></item><item><p>If the context item is a childless node (such as a text node), then
                              both the pre-descent and post-descent values of the accumulator can be
                              computed before evaluating any user-written constructs that access
                              this node; there are therefore no constraints on where a call to
                                 <function>accumulator-after</function> can appear.</p></item><item><p>This rule ensures that when computing the pre-descent value of an
                              accumulator for a particular streamed node, the post-descent values of
                              accumulators for that node are not available.</p></item><item><p>This rule states that the post-descent value of an accumulator is
                              allowed to depend on the post-descent values of other accumulators for
                              the same node. There is a rule preventing cycles <xerrorref spec="XT40" class="DE" code="3400"/>.</p></item><item><p>This rule prevents the use of the function (when applied to a streamed
                              node) in contexts like the <code nobreak="false">use</code> attribute of
                                 <elcode>xsl:key</elcode>. It
                                 allows its use in the attributes of an <xtermref spec="XT40" ref="dt-instruction"/> or <xtermref spec="XT40" ref="dt-literal-result-element"/>, 
                             or in a <xtermref spec="XT40" ref="dt-text-value-template"/>. It does not allow use in an
                                    <elcode>xsl:sort</elcode> or <elcode>xsl:param</elcode> element,
                                 as these elements do not form part of a sequence constructor (see
                                    <xspecref spec="XT40" ref="sequence-constructors"/>).</p></item><item><p>This rule prevents the use of the function (when applied to a streamed
                              node) in contexts such as predicates, or the right-hand side of the
                              <code nobreak="false">/</code> operator. The focus for evaluation of the function must be the
                              same as the focus for a containing sequence constructor. Sequence
                              constructors are treated differently from all other constructs for
                              this purpose in that their operands (the contained instructions) are
                              treated as ordered: in conjunction with the next rule, this rule is
                              assuming that instructions in a sequence constructor that follow a
                                 <termref def="dt-consuming"/> instruction are evaluated after the
                                 <termref def="dt-consuming"/> instruction and therefore have access
                              to the post-descent accumulator value.</p></item><item><p>This rule is subtle, and has a number of consequences. In these notes, the term
                                    <term>instruction</term> should be read as including all nodes
                                 making up a sequence constructor, including XSLT instructions,
                                 extension instructions, literal result elements, and text nodes
                                 containing text value templates.</p><ulist><item><p>In a sequence constructor that contains a <termref def="dt-consuming"/> instruction such as
                                       <code nobreak="false">&lt;xsl:apply-templates/&gt;</code>, it allows any
                                    number of calls on <function>accumulator-after</function> to
                                    appear in instructions that follow the call on
                                       <code nobreak="false">&lt;xsl:apply-templates/&gt;</code>.</p></item><item><p>In such a sequence constructor it prevents a call on
                                       <function>accumulator-after</function> from appearing in an
                                    instruction that precedes the
                                       <code nobreak="false">&lt;xsl:apply-templates/&gt;</code>, because there
                                    would then be two <termref def="dt-consuming"/>
                                    instructions.</p></item><item><p>In a sequence constructor that contains calls on
                                       <function>accumulator-after</function>, and contains no other
                                       <termref def="dt-consuming"/> construct, the first
                                    instruction that contains a call on
                                       <function>accumulator-after</function> is consuming (unless
                                    it contains more than one such call, in which case it is
                                    free-ranging), and subsequent instructions containing such a
                                    call are motionless. So it is possible to have two or more calls
                                    on <function>accumulator-after</function> provided they appear
                                    in different instructions, which allows the analysis to assume
                                    an order of execution.</p></item><item><p>It prevents a call on <function>accumulator-after</function>
                                    from appearing in the same instruction as another consuming
                                    construct: for example it disallows <code nobreak="false">concat(child::p,
                                       accumulator-after('a'))</code>. This rule preserves the
                                    ability to evaluate the arguments of the <code nobreak="false">concat</code>
                                    function in any order.</p></item><item><p>It disallows a call on <function>accumulator-after</function>
                                    from appearing in a sequence constructor that is required to be
                                    motionless, for example within <elcode>xsl:sort</elcode>.</p></item><item><p>The reference to a “preceding sibling node within the same
                                    sequence constructor” is carefully worded to ensure that
                                    preceding siblings among the children of
                                       <elcode>xsl:fork</elcode> are not taken into account; the
                                    children of <elcode>xsl:fork</elcode> are sibling instructions,
                                    but do not constitute a sequence constructor. The term also excludes elements such as
                                          <elcode>xsl:param</elcode> and <elcode>xsl:sort</elcode>
                                       that may precede a sequence constructor but are not part of
                                       it.</p></item></ulist></item><item><p>The final rule states that if none of the previous rules apply, the
                              function is considered motionless. This applies when the
                                 <function>accumulator-after</function> appears after a consuming
                              instruction within the same sequence constructor.</p><p>Note also that a call to <function>accumulator-after</function> can
                              safely appear within a construct such as a named template or
                              (non-streamable) stylesheet function; this is safe because the rules
                              ensure that in such situations, the context item cannot be a streamed
                              node.</p></item></olist></note><p>Dynamic invocation of <function>accumulator-after</function> is covered by the
                     rules in <xspecref spec="XT40" ref="function-lookup"/>. These rules ensure that a function
                     item cannot include a streamed node in its closure; circumventing the
                     streamability rules for <function>accumulator-after</function> by making a
                     dynamic call is therefore not possible.</p></div3><div3 id="streamability-fn-accumulator-before"><head>Streamability of the <function>accumulator-before</function> Function</head><p>See also <specref ref="streamability-of-accumulators"/>.</p><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the function call are assessed as follows:</p><olist><item><p>If the argument to <function>accumulator-before</function> is motionless,
                           the function call is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item><item><p>Otherwise, the function call is <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item></olist></div3><div3 id="streamability-fn-current"><head>Streamability of the <function>current</function> Function</head><p>The <termref def="dt-sweep"/> and <termref def="dt-posture"/> of a call to the
                        <function>current</function> function are determined as follows:</p><olist><item><p>If the call appears within a pattern, then climbing and motionless.</p><note><p>The call to <function>current</function> will always be within a predicate of the pattern.
                        The use of climbing posture here allows predicates such as <code nobreak="false">[@class = current()/@class]</code>,
                        while disallowing downwards navigation from the node returned by the function.</p></note></item><item><p>Otherwise, let <var>E</var> be the outermost containing XPath expression of the call
                           to the <function>current</function> function.</p></item><item><p>If the <termref def="dt-context-posture"/> of <var>E</var> is <termref def="dt-grounded"/>, then <termref def="dt-motionless"/> and <termref def="dt-grounded"/>.</p></item><item><p>If the path in the expression tree that connects the call on
                              <function>current</function> to <var>E</var> (excluding <var>E</var>
                           itself) contains an expression that is a <termref def="dt-higher-order-operand"/> of its parent expression, then
                              <termref def="dt-motionless"/> and <termref def="dt-climbing"/>. </p><note><p>Many common uses of the <function>current</function>, such as
                                 <code nobreak="false">//p[@class=current()/@class]</code>, fall into this category:
                              a predicate is a higher-order operand of its containing filter
                              expression.</p><p>The use of <termref def="dt-climbing"/> posture here might seem
                              unrelated to its usual connection with the ancestor axis. The
                              explanation (apart from the fact that it happens to produce the right
                              results) lies in the fact that at the point where the
                                 <function>current</function> call is evaluated, the node it returns
                              will always be an ancestor-or-self of the context node, as a
                              consequence of the fact that the containing XPath expression is
                              required to be either <termref def="dt-motionless"/> or <termref def="dt-consuming"/>.</p><p>The effect of the rule is to allow
                              expressions such as <code nobreak="false">//*[name() = name(current())]</code> or
                                 <code nobreak="false">//*[@ref = current()/@id]</code>.</p></note></item><item><p>Otherwise, the <termref def="dt-posture"/> is the 
                        <termref def="dt-context-posture"/>, and the <termref def="dt-sweep"/> is 
                        <termref def="dt-motionless"/>.</p></item></olist><!--<note><p>Although the <function>current</function> function is supported for streaming, it needs to be
                  used with care. Some common use cases such as <code>select="$lookup[@name = current()/name]</code> will fail,
                  because the streamability rules require a predicate to be motionless. A workaround is to extract the relevant value into a variable:
                     <code>select="let $n := string(name) return $lookup[@name = $n]</code>; in turn this removes the need for the <function>current</function>
                     function.</p>
                     <p>The use of the <function>current</function> function within a pattern is supported with similar restrictions. 
                        In this case the
                     <phrase diff="chg" at="Q"><termref def="dt-context-posture"/></phrase> is always <termref def="dt-striding"/>.</p></note>--></div3><div3 id="streamability-fn-current-group"><head>Streamability of the <function>current-group</function> Function</head><p>The <termref def="dt-sweep"/> and <termref def="dt-posture"/> of a call <var>C</var> to the
                        <function>current-group</function> function are as follows:</p><olist><item><p>If all the following conditions are true:</p><olist><item><p><var>C</var> has a containing <elcode>xsl:for-each-group</elcode>
                                 instruction (call it <var>F</var>)</p></item><item><p>The path in the construct tree that connects <var>C</var> to the
                                 sequence constructor forming the body of <var>F</var> is such that
                                 no child construct is a <termref def="dt-higher-order-operand"/> of
                                 its parent</p></item><item><p>The <termref def="dt-focus-setting-container"/>
                                 of <var>C</var> is <var>F</var></p></item></olist><p>then the <termref def="dt-sweep"/> and <termref def="dt-posture"/> of
                              <var>C</var> are the <termref def="dt-sweep"/> and <termref def="dt-posture"/> of the <code nobreak="false">select</code> expression of
                              <var>F</var>.</p></item><item><p>Otherwise, <termref def="dt-roaming"/> and <termref def="dt-free-ranging"/>.</p></item></olist><note><p>Informally, for streamed evaluation to be possible, a call to
                           <function>current-group</function> must not appear in a construct that is
                        evaluated repeatedly. For example, the expression <code nobreak="false">for $i in 1 to 10
                           return current-group()</code> would not be streamable.</p></note></div3><div3 id="streamability-fn-current-grouping-key"><head>Streamability of the <function>current-grouping-key</function>
                     Function</head><p>A call to the
                        <function>current-grouping-key</function> function is grounded and
                     motionless.</p></div3><div3 id="streamability-fn-current-merge-group"><head>Streamability of the <function>current-merge-group</function>
                     Function</head><p>A call to the
                        <function>current-merge-group</function> function is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p><note><p>This is because the nodes to be merged are always snapshots, and therefore
                           <termref def="dt-grounded"/>: see <specref ref="streamable-merging"/>.</p></note></div3><div3 id="streamability-fn-current-merge-key"><head>Streamability of the <function>current-merge-key</function> Function</head><p>A call to the <function>current-merge-key</function> function is 
                     <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></div3><div3 id="streamability-fn-current-merge-key-array"><head>Streamability of the <function>current-merge-key-array</function> Function</head><p>A call to the <function>current-merge-key-array</function> 
                     function is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></div3><div3 id="streamability-fn-distinct-ordered-nodes"><head>Streamability of the <function>distinct-ordered-nodes</function> Function</head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of a call to the
                     <function>distinct-ordered-nodes</function> function are the same as the
                     <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the first argument.</p></div3><div3 id="streamability-fn-fold-left"><head>Streamability of the <xfunction>fold-left</xfunction> Function</head><p>The function call <code nobreak="false">fold-left($seq, $zero, $f)</code>, follows the <termref def="dt-general-streamability-rules"/>, with the first argument
                        <code nobreak="false">$seq</code> having <termref def="dt-type-determined-usage"/> based on
                     the type of the second argument of the function supplied as
                     <code nobreak="false">$f</code>.</p><p>For example, given the call <code nobreak="false">fold-left(/*/transaction, 0, fn($x as
                        xs:decimal, $y as xs:decimal) as xs:decimal { $x + $y })</code>, the <termref def="dt-operand-usage"/> of the argument <code nobreak="false">/*/transaction</code> is
                     determined by the declared type of <code nobreak="false">$y</code>, namely
                        <code nobreak="false">xs:decimal</code>. Since this is an atomic type, the <termref def="dt-type-determined-usage"/> is <termref def="dt-absorption"/>. Applying
                     this to the general streamability rules, the function call is <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></div3><div3 id="streamability-fn-fold-right"><head>Streamability of the <xfunction>fold-right</xfunction> Function</head><p>The function follows the <termref def="dt-general-streamability-rules"/>, with
                     the first argument having <termref def="dt-operand-usage"/>
                     <termref def="dt-navigation"/> to reflect the fact that the supplied sequence
                     is processed in reverse order.</p><note><p>The same considerations apply as for the <xfunction>reverse</xfunction>
                        function: see <specref ref="streamability-fn-reverse"/>.</p></note></div3><div3 id="streamability-fn-foot"><head>Streamability of the <xfunction>foot</xfunction> Function</head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the expression
                     <code nobreak="false">foot($x)</code> are defined to be the same as the <termref def="dt-posture"/> 
                     and <termref def="dt-sweep"/> of the equivalent expression <code nobreak="false">$x[position()=last()]</code>.
                     See <specref ref="streamability-fn-last"/>.</p></div3><div3 id="streamability-fn-for-each"><head>Streamability of the <xfunction>for-each</xfunction> Function</head><p>The function call <code nobreak="false">for-each($seq, $f)</code>, follows the <termref def="dt-general-streamability-rules"/>, with the first argument
                        <code nobreak="false">$seq</code> having <termref def="dt-type-determined-usage"/> based on
                     the type of the (single) argument of the function supplied as
                     <code nobreak="false">$f</code>.</p><p>For example, given the call <code nobreak="false">for-each(/*/transaction, fn($x as
                        xs:decimal) as xs:decimal {abs($x)})</code>, the <termref def="dt-operand-usage"/> of the argument <code nobreak="false">/*/transaction</code> is
                     determined by the declared type of <code nobreak="false">$x</code>, namely
                        <code nobreak="false">xs:decimal</code>. Since this is an atomic type, the <termref def="dt-type-determined-usage"/> is <termref def="dt-absorption"/>. Applying
                     this to the general streamability rules, the function call is <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p><note><p>In practice, the <xfunction>filter</xfunction> function is streamable if
                        either (a) the supplied sequence is grounded, or (b) the supplied function
                        is statically known to atomize its argument.</p></note></div3><div3 id="streamability-fn-for-each-pair"><head>Streamability of the <xfunction>for-each-pair</xfunction> Function</head><p>The function call <code nobreak="false">for-each($seq1, $seq2, $f)</code>, follows the <termref def="dt-general-streamability-rules"/>, where:</p><olist><item><p>The first argument <code nobreak="false">$seq1</code> has <termref def="dt-type-determined-usage"/> based on the type of the first
                              argument of the function supplied as <code nobreak="false">$f</code>.</p></item><item><p>The second argument <code nobreak="false">$seq2</code> has <termref def="dt-type-determined-usage"/> based on the type of the second
                              argument of the function supplied as <code nobreak="false">$f</code></p></item></olist><note><p>In practice, the <xfunction>for-each-pair</xfunction> function is streamable
                        provided (a) at most one of the input sequences is consuming, and (b) either
                        (i) that input sequence is grounded, or (ii) the supplied function is
                        statically known to atomize the relevant argument.</p><p>If it is necessary to combine two sequences that are both streamed, consider
                        using <elcode>xsl:merge</elcode>.</p></note></div3><div3 id="streamability-fn-function-lookup"><head>Streamability of the <xfunction>function-lookup</xfunction> Function</head><p>See <xspecref spec="XT40" ref="function-lookup"/> for special rules that relate to
                     streamability of calls to the <xfunction>function-lookup</xfunction>
                     function.</p><p>With the caveats given there, the function follows the <termref def="dt-general-streamability-rules"/>, for a function with two arguments
                     that both have <termref def="dt-operand-usage"/>
                     <termref def="dt-absorption"/>.</p></div3><div3 id="streamability-fn-innermost"><head>Streamability of the <xfunction>innermost</xfunction> Function</head><p>The function follows the <termref def="dt-general-streamability-rules"/>, with
                     the first argument having <termref def="dt-operand-usage"/>
                     <termref def="dt-navigation"/>. This is to reflect the fact that the processing
                     is not strictly sequential: it cannot be determined that a node is part of the
                     result sequence of <xfunction>innermost</xfunction> until all its descendants
                     have been read.</p></div3><div3 id="streamability-fn-last"><head>Streamability of the <xfunction>last</xfunction> Function</head><p>If the <termref def="dt-context-posture"/> for a call on the
                        <xfunction>last</xfunction> function is <termref def="dt-striding"/>,
                        <termref def="dt-crawling"/>, or <termref def="dt-roaming"/>, then the
                        <termref def="dt-posture"/> of the function is <termref def="dt-roaming"/>,
                     and the <termref def="dt-sweep"/> is <termref def="dt-free-ranging"/>.</p><p>In all other cases the function is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p><note><p>The cases where <xfunction>last</xfunction> can be used without affecting
                        streamability are where the context item is either <termref def="dt-grounded"/> or <termref def="dt-climbing"/>. The latter condition
                        makes expressions like <code nobreak="false">ancestor::*[@xml:space][last()]</code>
                        streamable.</p><p>There are special rules restricting the use of <xfunction>last</xfunction>
                        in the predicate of a pattern: see <specref ref="classifying-patterns"/>.</p><p>Note that there are no restrictions preventing the
                     use of <code nobreak="false">last()</code> when the context posture is grounded. The implications of
                     this are discussed in <specref ref="grounded-consuming-constructs"/>. In the case where
                     the sequence being processed is delivered by a consuming expression, using <code nobreak="false">last()</code>
                     may result in this sequence being buffered in memory.</p></note></div3><div3 id="streamability-fn-outermost"><head>Streamability of the <xfunction>outermost</xfunction> Function</head><p>The single argument to this function has <termref def="dt-operand-usage"/>
                     <termref def="dt-transmission"/>.</p><p>The streamability of the function call follows the <termref def="dt-general-streamability-rules"/> with one exception: if the <termref def="dt-posture"/> of the argument is <termref def="dt-crawling"/>, then the
                     posture of the result is <termref def="dt-striding"/>.</p><note><p>There are cases where the streaming rules allow the construct
                           <code nobreak="false">outermost(//para)</code> but do not allow <code nobreak="false">//para</code>; the
                        function can therefore be useful in cases where it is known that
                           <code nobreak="false">para</code> elements will not be nested, as well as cases where the
                        application actually wishes to process all <code nobreak="false">para</code> elements except
                        those that are nested within another.</p><p>By contrast, the <xfunction>innermost</xfunction> function offers no
                        streaming benefits. Although it delivers a subset of the input nodes as its
                        result, in the correct order, it is classed as navigational because it needs
                        to look ahead in the input stream before deciding whether a node can be
                        included in the result.</p></note></div3><div3 id="streamability-fn-position"><head>Streamability of the <xfunction>position</xfunction> Function</head><p>The <xfunction>position</xfunction> function follows the <termref def="dt-general-streamability-rules"/>. Since it has no operands, this means
                     it is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p><note><p>Within an expression, there are no special difficulties in evaluating the
                           <xfunction>position</xfunction> function.</p><p>It does have special treatment within a predicate of a <xtermref spec="XT40" ref="dt-pattern"/>, however: a pattern is not motionless if it contains a
                        call to <xfunction>position</xfunction>, as explained in <specref ref="classifying-patterns"/>. </p></note></div3><div3 id="streamability-fn-reverse"><head>Streamability of the <xfunction>reverse</xfunction> Function</head><p>The <xfunction>reverse</xfunction> function follows the <termref def="dt-general-streamability-rules"/>, with its operand classified as
                     having <termref def="dt-operand-usage"/>
                     <termref def="dt-navigation"/>.</p><note><p>This means in effect that a call on <xfunction>reverse</xfunction> is not
                        streamable unless the operand is grounded. This may cause few surprises:</p><ulist><item><p>The expression <code nobreak="false">reverse(/*/emp/copy-of())</code> is considered
                              streamable, although all the <code nobreak="false">emp</code> elements will typically
                              need to be in memory at the same time. The explanation here is that
                              the streamability rules do not attempt to restrict the amount of
                              memory used for data that is explicitly copied by use of a function
                              such as <function>copy-of</function>.</p></item><item><p>The expression <code nobreak="false">reverse(ancestor::*)/name()</code> is considered
                              non-streamable, because the operand is not grounded. This problem can
                              be circumvented by rewriting the expression as
                                 <code nobreak="false">reverse(ancestor::*/name())</code></p></item></ulist></note></div3><div3 id="streamability-fn-root"><head>Streamability of the <xfunction>root</xfunction> Function</head><p>The zero-argument function <code nobreak="false">root()</code> is equivalent to
                        <code nobreak="false">root(.)</code>.</p><p>Given the expression <code nobreak="false">root(X)</code>, if the <termref def="dt-static-type"/> of <code nobreak="false">X</code> is <var>U{document-node()}</var>, and if its <termref def="dt-posture"/> is <termref def="dt-striding"/>, then
                        <code nobreak="false">root(X)</code> is rewritten as <code nobreak="false">X</code>. Otherwise, it is
                     rewritten as <code nobreak="false">head((X)/ancestor-or-self::node())</code>. Streamability
                     analysis is then applied to the rewritten expression.</p><note><p>Because path expressions starting with <code nobreak="false">/</code> are rewritten to use
                        the <xfunction>root</xfunction> function, this ensures that a leading slash
                        is ignored if the context item is a document node, for example within a
                        template rule with <code nobreak="false">match="/"</code>. This improves streamability,
                        because upwards navigation followed by downward navigation is
                        disallowed.</p></note></div3><div3 id="streamability-fn-trunk"><head>Streamability of the <xfunction>trunk</xfunction> Function</head><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the expression
                     <code nobreak="false">trunk($x)</code> are defined to be the same as the <termref def="dt-posture"/> 
                     and <termref def="dt-sweep"/> of the equivalent expression <code nobreak="false">$x[position()!=last()]</code>.
                     See <specref ref="streamability-fn-last"/>.</p></div3><!--<div4 id="streamability-fn-unparsed-entity-public-id">
                  <head>Streamability of the <function>unparsed-entity-public-id</function> function</head>
                  <p>The function <function>unparsed-entity-public-id</function> has an implicit dependency on the context item.</p>
                  <p>If the context item type is anything other than a document node, the function works without difficulty in streaming mode: in the same way
                  as attributes of ancestor elements are retained and are available while processing descendant elements, the unparsed entities
                  declared in the DTD are retained while processing the body of the document.</p>
                  <p>While processing the document node itself, however, the contents of the DTD might not yet be available. An arbitrary number
                  of comments and processing instructions are allowed to precede the DTD. </p>
                  <p>So the rules are:</p>
                  <ulist>
                     <item><p>If the <phrase diff="chg" at="Q"><termref def="dt-context-posture"/></phrase> is grounded, the posture is grounded and the sweep is motionless</p></item>
                     <item><p>If the <phrase diff="chg" at="Q"><termref def="dt-context-posture"/></phrase> is roaming, the posture is roaming and the sweep is free-ranging</p></item>
                     <item><p>If the <phrase diff="chg" at="Q"><termref def="dt-context-posture"/></phrase> is climbing, striding, or crawling, the context item type permits a document node, then the posture is crawling
                     and the sweep is consuming</p></item>
                     <item><p>If the <phrase diff="chg" at="Q"><termref def="dt-context-posture"/></phrase> is climbing, striding, or crawling, the context item type does not permit a document node, then the posture is grounded
                        and the sweep is motionless</p></item>
                  </ulist>
               </div4>
               <div4 id="streamability-fn-unparsed-entity-uri">
                  <head>Streamability of the <function>unparsed-entity-uri</function> function</head>
                  <p>The streamability characteristics of this function are the same as <function>unparsed-entity-public-id</function>:
                     see <specref ref="streamability-fn-unparsed-entity-public-id"/>.</p>
               </div4>--></div2><div2 id="classifying-patterns"><head>Classifying Patterns</head><note><p>Patterns differ from other kinds of construct in that they are not composable
                     in the same way. It is best to think of a pattern as specialized syntax for a
                     function that takes an item as its argument and returns a boolean: <code nobreak="false">true</code> if the
                     pattern matches the item, otherwise <code nobreak="false">false</code>. The <termref def="dt-static-type"/> of a pattern is therefore taken as
                           <var>U{xs:boolean}</var> (this is not to be confused with the type of the
                        items that the pattern is capable of matching).</p></note><p>The <termref def="dt-sweep"/> of a <xtermref spec="XT40" ref="dt-pattern"/>
                  is either <termref def="dt-motionless"/> or <termref def="dt-free-ranging"/>.
                  (Although there are patterns that could in principle be evaluated by consuming the
                  element node that they match, these are of no interest in the analysis, so they
                  are classified as free-ranging.)</p><p>The <termref def="dt-posture"/> of a <xtermref spec="XT40" ref="dt-pattern"/>
                  is <termref def="dt-grounded"/> if the pattern is <termref def="dt-motionless"/>,
                  or <termref def="dt-roaming"/> otherwise. (This reflects the fact that a pattern
                  always returns a boolean result; it never returns a node in a streamed
                  document.)</p><p>Informally, a <termref def="dt-motionless"/> pattern is one that
                  can be evaluated by a streaming processor when the input stream is positioned at
                  the start of the node being matched, without
                  advancing the input stream.</p><p>A pattern is <termref def="dt-motionless"/> if and only if it satisfies all the following
                     conditions:</p><olist><item><p>The pattern does not contain a <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XT40" ref="RootedPath" xlink:type="simple">RootedPath</xnt>.</p></item><item><p>If the pattern contains predicates, then every top-level
                           <code nobreak="false">Predicate</code> in the pattern satisfies all the following
                        conditions:</p><olist><item><p>The expression immediately contained in the predicate is <termref def="dt-motionless"/>, when assessed with
                                 a <termref def="dt-context-posture"/> of <termref def="dt-striding"/>, and a context item type set to the <termref def="dt-static-type"/> of the expression to which the predicate
                                 applies, determined using the rules in <specref ref="determining-static-type"/>.</p></item><item><p>The predicate is a <termref def="dt-non-positional-predicate"/>.</p></item></olist><p>The use of the term <term>top-level</term> in this rule means that
                        predicates that are nested within other predicates do not themselves have to
                        be non-positional, though they may play a role in the analysis of top-level
                        predicates.</p></item><item><p>The pattern does not contain (at any depth) a variable reference that is
                        bound to a <termref def="dt-streaming-parameter"/>. (See <specref ref="streamability-of-function-calls"/>).</p></item></olist><p><termdef id="dt-non-positional-predicate" term="non-positional predicate" open="true">A predicate is a <term>non-positional
                        predicate</term> if it satisfies both of the following
                  conditions:</termdef></p><olist><item><p>The predicate does not contain a function call or named function reference
                        to any of the following functions, unless that call or reference occurs
                        within a nested predicate:</p><olist><item><p><xfunction>position</xfunction></p></item><item><p><xfunction>last</xfunction></p></item><item><p><xfunction>function-lookup</xfunction>.</p></item></olist><note><p>The exception for nested predicates is there to ensure that patterns
                           such as <code nobreak="false">match="p[@code = $status[last()]]</code> are not disqualified.</p></note></item><item><p>The expression immediately contained in the
                        predicate is a non-numeric expression. An expression is non-numeric if
                           the intersection of its <termref def="dt-static-type"/> (see <specref ref="determining-static-type"/>)
                           with <var>U{xs:decimal, xs:double, xs:float}</var> is
                           <var>U{}</var>.</p></item></olist><p role="closetermdef"/><note><p>A non-positional predicate can be evaluated by
                     considering each item in the filtered sequence independently; the result never
                     depends on the position of other items in the sequence or the length of the
                     sequence.</p></note><p>A pattern that is not <termref def="dt-motionless"/> is classified as <termref def="dt-free-ranging"/>.</p><p>The following list shows examples of motionless
                  patterns:</p><ulist><item><p><code nobreak="false">/</code></p></item><item><p><code nobreak="false">*</code></p></item><item><p><code nobreak="false">/*</code></p></item><item><p><code nobreak="false">p</code></p></item><item><p><code nobreak="false">p|q</code></p></item><item><p><code nobreak="false">p/q</code></p></item><item><p><code nobreak="false">p[@status='red']</code></p></item><item><p><code nobreak="false">p[base-uri()]</code></p></item><item><p><code nobreak="false">p[@class or @style]</code></p></item><item><p><code nobreak="false">p[@status]</code></p></item><item><p><code nobreak="false">p[@status = $status-codes[1]]</code></p></item><item><p><code nobreak="false">p[@class | @style]</code></p></item><item><p><code nobreak="false">p[contains(@class, ':')]</code></p></item><item><p><code nobreak="false">p[substring-after(@class, ':')]</code></p></item><item><p><code nobreak="false">p[ancestor::*[@xml:lang]]</code></p></item><item><p><code nobreak="false">text()[starts-with(., '$')]</code></p></item><item><p><code nobreak="false">@price</code></p></item><item><p><code nobreak="false">@price[starts-with(., '$')]</code></p></item><item><p><code nobreak="false">//p/text()[. = 'Introduction']</code></p></item><item><p><code nobreak="false">document-node(element(html))</code> (Note:
                        this is classified as motionless even though testing a document node against
                        the pattern might require a small amount of look-ahead.)</p></item></ulist><p>The following list shows examples of patterns that are
                  not motionless, explaining why not:</p><ulist><item><p><code nobreak="false">id('abc')</code> (contains a <code nobreak="false">RootedPath</code>)</p></item><item><p><code nobreak="false">$doc//p</code> (contains a <code nobreak="false">RootedPath</code>)</p></item><item><p><code nobreak="false">p[b]</code> (the predicate is not motionless)</p></item><item><p><code nobreak="false">p[. = 'Introduction']</code> (the predicate is not motionless)</p></item><item><p><code nobreak="false">p[starts-with(., '$')]</code> (the predicate is not motionless)</p></item><item><p><code nobreak="false">p[preceding-sibling::p[1] = '']</code> (the predicate is not
                        motionless)</p></item><item><p><code nobreak="false">p[1]</code> (contains a positional predicate: return type is
                        numeric)</p></item><item><p><code nobreak="false">p[$pnum + 1]</code> (contains a positional predicate: return type is
                        numeric)</p></item><item><p><code nobreak="false">p[data(@status)]</code> (contains a positional predicate: return type
                        is potentially numeric)</p></item><item><p><code nobreak="false">p[position() gt 2]</code> (contains a positional predicate: calls
                           <code nobreak="false">position()</code>)</p></item><item><p><code nobreak="false">p[last()]</code> (contains a positional predicate: calls
                           <code nobreak="false">last()</code>)</p></item></ulist></div2><div2 id="streamability-analysis-examples"><head>Examples of Streamability Analysis</head><p>The examples in this section are intended to illustrate how the streamability rules
               are applied “top down” to establish whether template rules are guaranteed
               streamable.</p><example><head>A recursive-descent template rule</head><p>Consider the following template rule, where mode <code nobreak="false">s</code> is defined with
                     <code nobreak="false">streamable="yes"</code>:</p><eg role="xslt-declaration" xml:space="preserve">
&lt;xsl:template match="para" mode="s"&gt;
  &lt;div class="para"&gt;
    &lt;xsl:apply-templates mode="s"/&gt;
  &lt;/div&gt;
&lt;/xsl:template&gt;</eg><p>The processor is required to establish that this template meets the streamability
                  rules. Specifically, as stated in <specref ref="streamable-templates"/>, it must
                  satisfy three conditions:</p><olist><item><p>The match pattern must be <termref def="dt-motionless"/>.</p></item><item><p>The body of the template rule must be <termref def="dt-grounded"/>.</p></item><item><p>The initializers of any template parameters must be <termref def="dt-motionless"/>.</p></item></olist><p>The third condition is satisfied trivially because there are no parameters.</p><p>The first rule depends on the rules for assessing patterns, which are given in
                     <specref ref="classifying-patterns"/>. This pattern is motionless because (a)
                  it does not contain a <code nobreak="false">RootedPath</code>, and (b) it contains no
                  predicates.</p><p>So it remains to determine that the body of the template is <termref def="dt-grounded"/>. The proof of this is as follows:</p><olist><item><p>The sequence constructor forming the body of the template is assessed
                        according to the rules in <specref ref="classifying-sequence-constructors"/>, which tell us that there is a single operand (the
                           <code nobreak="false">&lt;div&gt;</code>
                        <xtermref spec="XT40" ref="dt-literal-result-element"/>) which has <termref def="dt-operand-usage"/>
                        <var>U</var> = <termref def="dt-transmission"/>. </p></item><item><p>The assessment of the sequence constructor uses the <termref def="dt-general-streamability-rules"/>. These rules require us to
                        determine the type <var>T</var>, sweep <var>S</var>, posture <var>P</var>,
                        and usage <var>U</var> of each operand. We have already established that
                        there is a single operand, with <var>U</var> = <termref def="dt-transmission"/>. Section <specref ref="determining-static-type"/>
                        tells us that for all instructions, we can take <var>T</var> =
                           <var>U{*}</var>. The <termref def="dt-posture"/>
                        <var>P</var> and <termref def="dt-sweep"/>
                        <var>S</var> of the literal result element are established as follows:</p><olist><item><p>The rules for literal result elements (specifically the
                                 <code nobreak="false">&lt;div&gt;</code> element) are given in <specref ref="streamability-literal-result-elements"/>. This particular
                              literal result element has only one operand (its contained sequence
                              constructor), with <termref def="dt-operand-usage"/>
                              <var>U</var> = <termref def="dt-absorption"/>.</p></item><item><p>The <termref def="dt-general-streamability-rules"/> again apply. Again
                              the <termref def="dt-static-type"/>
                              <var>T</var> of the operand is <code nobreak="false">U{*}</code>, and we need to
                              determine the <termref def="dt-posture"/>
                              <var>P</var> and <termref def="dt-sweep"/>
                              <var>S</var>.</p></item><item><p>To determine the posture and sweep of this sequence constructor (the
                              one that contains the <elcode>xsl:apply-templates</elcode>
                              instruction) we refer again to the <termref def="dt-general-streamability-rules"/>.</p><olist><item><p>The sequence constructor has a single operand (the
                                       <elcode>xsl:apply-templates</elcode> instruction); again
                                       <var>U</var> = <termref def="dt-transmission"/>, <var>T</var>
                                    = <var>U{*}</var>.</p></item><item><p>The <termref def="dt-posture"/>
                                    <var>P</var> and <termref def="dt-sweep"/>
                                    <var>S</var> of the <elcode>xsl:apply-templates</elcode>
                                    instruction are established as follows:</p><olist><item><p>The rules that apply are in <specref ref="streamability-xsl-apply-templates"/>.</p></item><item><p>Rule 1 does not apply because the <code nobreak="false">select</code>
                                          expression (which defaults to <code nobreak="false">child::node()</code>)
                                          is not <termref def="dt-grounded"/>. This is a consequence
                                          of the rules in <specref ref="streamability-of-axis-steps"/>, specifically:</p><olist><item><p>The <termref def="dt-context-posture"/> of the axis
                                                step is established by the template rule as a whole,
                                                as <termref def="dt-striding"/>.</p></item><item><p>Therefore rules 1 and 2 do not apply.</p></item><item><p>The statically inferred context item type is derived
                                                from the match pattern (<code nobreak="false">match="para"</code>).
                                                This gives a type of <var>U{element()}</var>. The
                                                child axis for element nodes is not necessarily
                                                empty, so rule 3 does not apply.</p></item><item><p>Rule 4 does not apply because there are no
                                                predicates.</p></item><item><p>So the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the axis step
                                                  <code nobreak="false">child::node()</code> are given by the table
                                                in rule 5. The entry for (context posture =
                                                striding, axis = child) gives a posture of <termref def="dt-striding"/> and a <termref def="dt-sweep"/> of <termref def="dt-consuming"/>.</p></item><item><p>So the <code nobreak="false">select</code> expression is not
                                                  <termref def="dt-grounded"/>. (The same result can
                                                be reached intuitively: an expression that selects
                                                streamed nodes will never be <termref def="dt-grounded"/>.)</p></item></olist></item><item><p>Rule 2 does not apply because there is no
                                             <elcode>xsl:sort</elcode> element.</p></item><item><p>Rule 3 does not apply because the mode is declared with
                                             <code nobreak="false">streamable="yes"</code>.</p></item><item><p>So the <termref def="dt-posture"/>
                                          <var>P</var> and <termref def="dt-sweep"/>
                                          <var>S</var> of the <elcode>xsl:apply-templates</elcode>
                                          instruction are established by the <termref def="dt-general-streamability-rules"/>, as follows:</p><olist><item><p>There is a single operand, the implicit
                                                  <code nobreak="false">select="child::node()"</code> expression,
                                                with usage <var>U</var> = <termref def="dt-absorption"/>.</p></item><item><p>We have already established that for this operand,
                                                the posture <var>P</var> = <termref def="dt-striding"/> and the <termref def="dt-sweep"/>
                                                <var>S</var> = <termref def="dt-consuming"/>.</p></item><item><p>By the rules in <specref ref="determining-static-type"/>, the type
                                                  <var>T</var> of the <code nobreak="false">select</code> expression
                                                is <code nobreak="false">node()</code>.</p></item><item><p>In the <termref def="dt-general-streamability-rules"/>, the adjusted sweep <var>S'</var> for an operand
                                                with (<var>P</var> = <termref def="dt-striding"/>,
                                                  <var>U</var> = <termref def="dt-absorption"/>) is
                                                  <termref def="dt-consuming"/>, </p></item><item><p>Rule 2(d) then applies, so the
                                                  <elcode>xsl:apply-templates</elcode> instruction
                                                is <termref def="dt-consuming"/> and <termref def="dt-grounded"/>.</p></item></olist></item></olist></item><item><p>So the sequence constructor that contains the
                                       <elcode>xsl:apply-templates</elcode> instruction has one
                                    operand with <var>U</var> = <termref def="dt-transmission"/>,
                                       <var>T</var> = <code nobreak="false">item()</code>, <var>P</var> = <termref def="dt-grounded"/>, <var>S</var> = <termref def="dt-consuming"/>. Rule 2(d) of the <termref def="dt-general-streamability-rules"/> applies, so the
                                    sequence constructor itself has <var>P</var> = <termref def="dt-grounded"/>, <var>S</var> = <termref def="dt-consuming"/>.</p></item></olist></item><item><p>So the literal result element has one operand with <var>U</var> =
                                 <termref def="dt-absorption"/>, <var>T</var> = <code nobreak="false">item()</code>,
                                 <var>P</var> = <termref def="dt-grounded"/>, <var>S</var> =
                                 <termref def="dt-consuming"/>. Rule 2(d) of the <termref def="dt-general-streamability-rules"/> applies, so the literal
                              result element has <var>P</var> = <termref def="dt-grounded"/>,
                                 <var>S</var> = <termref def="dt-consuming"/>.</p></item></olist></item><item><p>So the sequence constructor containing the literal result element has one
                        operand with <var>U</var> = <termref def="dt-transmission"/>, <var>T</var> =
                           <code nobreak="false">item()</code>, <var>P</var> = <termref def="dt-grounded"/>,
                           <var>S</var> = <termref def="dt-consuming"/>. Rule 2(d) of the <termref def="dt-general-streamability-rules"/> applies, so this sequence
                        constructor itself has <var>P</var> = <termref def="dt-grounded"/>,
                           <var>S</var> = <termref def="dt-consuming"/>.</p></item><item><p>So we have established that the sequence constructor forming the body of the
                        template rule is <termref def="dt-grounded"/>.</p></item></olist><p>Therefore, since the other conditions are also satisfied, the template is <termref def="dt-guaranteed-streamable"/>.</p><p>The analysis presented above could have been simplified by taking into account the
                  fact that the streamability properties of a sequence constructor containing a
                  single instruction are identical to the properties of that instruction. This
                  simplification will be exploited in the next example.</p></example><example><head>An aggregating template rule</head><p>Consider the following template rule, where mode <code nobreak="false">s</code> is defined with
                     <code nobreak="false">streamable="yes"</code>:</p><eg role="xslt-declaration" xml:space="preserve">
&lt;xsl:template match="transactions[@currency='USD']" mode="s"&gt;
  &lt;total&gt;&lt;xsl:value-of select="sum(transaction/@value)"/&gt;&lt;/total&gt;
&lt;/xsl:template&gt;</eg><p>Again, as stated in <specref ref="streamable-templates"/>, it must satisfy three
                  conditions:</p><olist><item><p>The match pattern must be <termref def="dt-motionless"/>.</p></item><item><p>The body of the template rule must be <termref def="dt-grounded"/>.</p></item><item><p>The initializers of any template parameters must be <termref def="dt-motionless"/>.</p></item></olist><p>The third condition is satisfied trivially because there are no parameters.</p><p>The first rule depends on the rules for assessing patterns, which are given in
                     <specref ref="classifying-patterns"/>. This pattern is motionless because (a)
                  it is not a <code nobreak="false">RootedPath</code>, and (b) every predicate is <termref def="dt-motionless"/> and <termref def="dt-non-positional-predicate">non-positional</termref>. The analysis that proves the predicate is motionless
                  and non-positional proceeds as follows:</p><olist><item><p>First establish that the expression <code nobreak="false">@currency='USD'</code> is
                           <termref def="dt-motionless"/>, as follows:</p><olist><item><p>The predicate is a general comparison (<code nobreak="false">GeneralComp</code>) which
                              follows the <termref def="dt-general-streamability-rules"/>.</p></item><item><p>There are two operands: an <code nobreak="false">AxisStep</code> with a defaulted
                                 <code nobreak="false">ForwardAxis</code>, and a <code nobreak="false">Literal</code>. Both operand
                              roles are <termref def="dt-absorption"/>.</p></item><item><p>The left-hand operand has
                              type <var>T</var> = <code nobreak="false">attribute()</code>. Its <termref def="dt-posture"/> and <termref def="dt-sweep"/> are determined by
                              the rules in <specref ref="streamability-of-axis-steps"/>. The
                                 <termref def="dt-context-posture"/> is <termref def="dt-striding"/>, so the <termref def="dt-posture"/> and <termref def="dt-sweep"/>
                              are determined by the entry in the table (rule 5) with context posture
                              = <termref def="dt-striding"/>, axis = <code nobreak="false">attribute</code>: that
                              is, the result posture is <termref def="dt-striding"/> and the <termref def="dt-sweep"/>
                              is <termref def="dt-motionless"/>.</p></item><item><p>The right-hand operand,
                              being a literal, is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item><item><p>In the <termref def="dt-general-streamability-rules"/>, rule 2(e)
                              applies, so the predicate is <termref def="dt-grounded"/> and <termref def="dt-motionless"/></p></item></olist></item><item><p>Now establish that the expression <code nobreak="false">@currency='USD'</code> is
                           <termref def="dt-non-positional-predicate">non-positional</termref>, as
                        follows:</p><olist><item><p>Rule 1 is satisfied: the predicate does not call
                                 <xfunction>position</xfunction>, <xfunction>last</xfunction>, or
                                 <xfunction>function-lookup</xfunction>.</p></item><item><p>Rule 2 is satisfied: the expression <code nobreak="false">@currency='USD'</code> is
                              non-numeric. The <termref def="dt-static-type"/> of the expression is
                              determined using the rules in <specref ref="determining-static-type"/>
                              as <var>U{xs:boolean}</var>, and this has no intersection with
                                 <var>U{xs:decimal, xs:double, xs:float}</var>.</p></item></olist></item></olist><p>So both conditions in <specref ref="classifying-patterns"/> are satisfied, and the
                  pattern is therefore <termref def="dt-motionless"/>.</p><p>It remains to show that the body of the template rule is <termref def="dt-grounded"/>. The proof of this is as follows. Unlike the previous
                  example, the analysis is shown in simplified form; in particular the two sequence
                  constructors which each contain a single instruction are ignored, and replaced in
                  the construct tree by their contained instruction.</p><olist><item><p>We need to show that the <code nobreak="false">&lt;total&gt;</code>
                        <xtermref spec="XT40" ref="dt-literal-result-element"/> is <termref def="dt-grounded"/>.</p></item><item><p>The rules that apply are in <specref ref="streamability-literal-result-elements"/>.</p></item><item><p>These rules refer to the <termref def="dt-general-streamability-rules"/>.
                        There is one operand, the <elcode>xsl:value-of</elcode> child element, which
                        has <termref def="dt-operand-usage"/>
                        <var>U</var> = <termref def="dt-absorption"/>, and type <var>T</var> =
                           <code nobreak="false">item()</code>.</p></item><item><p>So we need to determine the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the <elcode>xsl:value-of</elcode> instruction.</p><olist><item><p>The rules are given in <specref ref="streamability-xsl-value-of"/>.</p></item><item><p>The <termref def="dt-general-streamability-rules"/> apply. There is
                              one operand, the expression <code nobreak="false">sum(transaction/@value)</code>,
                              which has <termref def="dt-operand-usage"/>
                              <var>U</var> = <termref def="dt-absorption"/>.</p></item><item><p>The type <var>T</var> of this operand is the return type defined in
                              the signature of the <xfunction>sum</xfunction> function, that is,
                                 <code nobreak="false">xs:anyAtomicType</code>.</p></item><item><p>The <termref def="dt-posture"/>
                              <var>P</var> and <termref def="dt-sweep"/>
                              <var>S</var> are established as follows:</p><olist><item><p>The rules that apply to the call on <xfunction>sum</xfunction>
                                    are given in <specref ref="classifying-built-in-functions"/>.</p></item><item><p>The relevant proforma is <code nobreak="false">fn:sum(A)</code>, indicating that
                                    the <termref def="dt-general-streamability-rules"/> apply, and
                                    that there is a single operand with usage <var>U</var> =
                                       <termref def="dt-absorption"/>.</p></item><item><p>The type <var>T</var> of the operand
                                       <code nobreak="false">transaction/@value</code> is determined (by the rules
                                    in <specref ref="determining-static-type"/>) as
                                       <code nobreak="false">attribute()</code>.</p></item><item><p>The <termref def="dt-posture"/>
                                    <var>P</var> and <termref def="dt-sweep"/>
                                    <var>S</var> of the operand <code nobreak="false">transaction/@value</code> are
                                    determined by the rules in <specref ref="streamability-of-path-expressions"/>, as follows:</p><olist><item><p>The expression is expanded to
                                             <code nobreak="false">child::transaction/attribute::value</code>.</p></item><item><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of the left-hand operand
                                             <code nobreak="false">child::transaction</code> are determined by the
                                          rules in <specref ref="streamability-of-axis-steps"/>, as
                                          follows:</p><olist><item><p>The <termref def="dt-context-posture"/> is <termref def="dt-striding"/>, because the <termref def="dt-focus-setting-container"/> is the template
                                                rule itself.</p></item><item><p>The <termref def="dt-context-item-type"/> is
                                                  <code nobreak="false">element()</code>, based on the <termref def="dt-match-type"/> of the pattern
                                                  <code nobreak="false">match="transactions[@currency='USD']"</code>.</p></item><item><p>Rules 1 and 2 do not apply because the <termref def="dt-context-posture"/> is <termref def="dt-striding"/>.</p></item><item><p>Rule 3 does not apply because the <code nobreak="false">child</code>
                                                axis applied to an element node is not necessarily
                                                empty.</p></item><item><p>Rule 4 does not apply because there are no
                                                predicates.</p></item><item><p>Rule 5 applies, and the table entry with context
                                                posture = <termref def="dt-striding"/>, axis =
                                                  <code nobreak="false">child</code> gives a result <termref def="dt-posture"/> of <termref def="dt-striding"/>
                                                and a <termref def="dt-sweep"/> of <termref def="dt-consuming"/>.</p></item></olist></item><item><p>The <termref def="dt-posture"/> of the relative path
                                          expression
                                             <code nobreak="false">child::transaction/attribute::value</code> is
                                          therefore the <termref def="dt-posture"/> of its right-hand operand
                                             <code nobreak="false">attribute::value</code>, assessed with a <termref def="dt-context-posture"/> of <termref def="dt-striding"/>. This is determined by the rules in
                                             <specref ref="streamability-of-axis-steps"/>, as
                                          follows:</p><olist><item><p>The <termref def="dt-context-posture"/>, as we have
                                                seen, is <termref def="dt-striding"/>.</p></item><item><p>The <termref def="dt-context-item-type"/> is
                                                  <code nobreak="false">element()</code>, based on the type of the
                                                  left-hand operand
                                                  <code nobreak="false">child::transaction</code>.</p></item><item><p>Rules 1 and 2 do not apply because the <termref def="dt-context-posture"/> is <termref def="dt-striding"/>.</p></item><item><p>Rule 3 does not apply because the
                                                  <code nobreak="false">attribute</code> axis applied to an element
                                                node is not necessarily empty.</p></item><item><p>Rule 4 does not apply because there are no
                                                predicates.</p></item><item><p>Rule 5 applies, and the table entry with context
                                                posture = <termref def="dt-striding"/>, axis =
                                                  <code nobreak="false">attribute</code> gives a result <termref def="dt-posture"/> of <termref def="dt-striding"/> and a <termref def="dt-sweep"/> of
                                                  <termref def="dt-motionless"/>.</p></item></olist></item><item><p>The <termref def="dt-posture"/> of the relative path
                                          expression
                                             <code nobreak="false">child::transaction/attribute::value</code> is
                                          therefore <termref def="dt-striding"/>.</p></item><item><p>The <termref def="dt-sweep"/> of the relative path
                                          expression
                                             <code nobreak="false">child::transaction/attribute::value</code> is the
                                          wider of the sweeps of its two operands, namely <termref def="dt-consuming"/> and <termref def="dt-motionless"/>. That is, it is <termref def="dt-consuming"/>.</p></item></olist></item><item><p>So the first and only operand to the call on <code nobreak="false">sum()</code>
                                    has <var>U</var> = <termref def="dt-absorption"/>, <var>T</var>
                                    = <code nobreak="false">attribute()</code>, <var>P</var> = <termref def="dt-climbing"/>, and <var>S</var> = <termref def="dt-consuming"/></p></item><item><p>Rule 1(b) of the <termref def="dt-general-streamability-rules"/>
                                    computes the adjusted sweep <var>S'</var>. Rule 1(b)(iii)(A)
                                    applies, so the effective <termref def="dt-operand-usage"/>
                                    <var>U'</var> is <termref def="dt-inspection"/>. Rule
                                    1(b)(iii)(A) then computes the adjusted sweep from the table
                                    entry for <var>P</var> = <termref def="dt-climbing"/>,
                                       <var>U'</var> = <termref def="dt-inspection"/>; this shows
                                       <var>S'</var> = <var>S</var>, that is, <termref def="dt-consuming"/>.</p></item><item><p>Rule 2(d) now applies, so the call on <code nobreak="false">sum()</code> is
                                       <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></item></olist></item><item><p>Since the <elcode>xsl:value-of</elcode> instruction has one operand
                              with <var>U</var> = <termref def="dt-absorption"/>, <var>T</var> =
                                 <code nobreak="false">xs:anyAtomicType</code>, <var>P</var> = <termref def="dt-grounded"/>, and <var>S</var> = <termref def="dt-consuming"/>, rule 2(d) again applies, and the <elcode>xsl:value-of</elcode>
                              instruction is <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></item></olist></item><item><p>Since the literal result element has one operand with <var>U</var> =
                           <termref def="dt-absorption"/>, <var>T</var> = <code nobreak="false">item()</code>,
                           <var>P</var> = <termref def="dt-grounded"/>, and <var>S</var> = <termref def="dt-consuming"/>, rule 2(d) again applies, and the literal result
                        element is <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></item><item><p>Therefore the body of the template rule is <termref def="dt-grounded"/>, and
                        since the other conditions are also satisfied, it is <termref def="dt-guaranteed-streamable"/>.</p></item></olist></example><example><head>Streamed Grouping</head><p>Consider the following code, which is designed to process a transaction file
                  containing transactions in chronological order, and output the total value of the
                  transactions for each day.</p><eg role="xslt-declaration" xml:space="preserve">
&lt;xsl:template name="go"&gt;
  &lt;out&gt;
    &lt;xsl:source-document streamable="yes" href="transactions.xml"&gt;
      &lt;xsl:for-each-group select="/account/transaction" 
                          group-adjacent="xs:date(@timestamp)"&gt;
         &lt;total date="{current-grouping-key()}" value="{sum(current-group()/@value)}"/&gt;
      &lt;/xsl:for-each-group&gt;
    &lt;/xsl:source-document&gt;
  &lt;/out&gt;
&lt;/xsl:template&gt;</eg><p>The rules for <elcode>xsl:source-document</elcode> say that the instruction is <termref def="dt-guaranteed-streamable"/> 
                 if the contained <xtermref spec="XT40" ref="dt-sequence-constructor"/> is <termref def="dt-grounded"/>, and the task
                  of streamability analysis is to prove that this is the case. As in the previous
                  example, we will take a short-cut by making the assumption that a sequence
                  constructor containing a single instruction can be replaced by that instruction in
                  the construct tree.</p><p>So the task is to show that the <elcode>xsl:for-each-group</elcode> instruction is
                     <termref def="dt-grounded"/>, which we can do as follows:</p><olist><item><p>The relevant rules are to be found in <specref ref="streamability-xsl-for-each-group"/>.</p><note><p>Rule numbers may be different in a version of the specification with
                           change markings.</p></note></item><item><p>Rule 1 applies only if the <code nobreak="false">select</code> expression is <termref def="dt-grounded"/>. It is easy to see informally that this is not the
                        case (an expression that returns streamed nodes is never grounded). More
                        formally:</p><olist><item><p>The <code nobreak="false">select</code> expression is a path expression; the rules in
                                 <specref ref="streamability-of-path-expressions"/> apply.</p></item><item><p>The expression is rewritten as <code nobreak="false">((root(.) treat as
                                 document-node())/child::account)/child::transaction</code></p></item><item><p>The left-hand operand <code nobreak="false">(root(.) treat as
                                 document-node())/child::account</code> is also a path expression,
                              so the rules in <specref ref="streamability-of-path-expressions"/>
                              apply recursively:</p><olist><item><p>The left-hand operand <code nobreak="false">root(.) treat as
                                       document-node()</code> follows the rules for a
                                       <code nobreak="false">TreatExpr</code> in <specref ref="classifying-expressions"/>; the proforma <code nobreak="false">T treat
                                       as TYPE</code> indicates that the <termref def="dt-general-streamability-rules"/> apply with a single
                                    operand having usage <termref def="dt-transmission"/>.</p></item><item><p>This single operand <code nobreak="false">root(.)</code> follows the rules in
                                       <specref ref="streamability-fn-root"/>. The item type of the
                                    operand <code nobreak="false">.</code> is the <termref def="dt-context-item-type"/>, which is the type established
                                    by the <elcode>xsl:source-document</elcode> instruction, namely
                                       <code nobreak="false">document-node()</code>. Under these conditions
                                       <code nobreak="false">root(.)</code> is rewritten as <code nobreak="false">.</code>, so the
                                       <termref def="dt-posture"/> is the <termref def="dt-context-posture"/> established by the
                                       <elcode>xsl:source-document</elcode> instruction, namely <termref def="dt-striding"/>. The <termref def="dt-sweep"/> is
                                       <termref def="dt-motionless"/>.</p></item><item><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                                    the expression <code nobreak="false">root(.) treat as document-node()</code> are
                                    the same as the <termref def="dt-posture"/> and <termref def="dt-sweep"/> of <code nobreak="false">root(.)</code>, namely <termref def="dt-striding"/> and <termref def="dt-motionless"/></p></item><item><p>The right-hand operand <code nobreak="false">child::account</code> is governed
                                    by the rules in <specref ref="streamability-of-axis-steps"/>.
                                    The <termref def="dt-context-posture"/> is <termref def="dt-striding"/>, and the axis is <code nobreak="false">child</code>, so
                                    the result posture is <termref def="dt-striding"/> and the sweep
                                    is <termref def="dt-consuming"/>.</p></item><item><p>The <termref def="dt-posture"/> of the path expression is the
                                       <termref def="dt-posture"/> of the right-hand operand, that
                                    is <termref def="dt-striding"/>, and its sweep is the wider
                                    sweep of the two operands, that is <termref def="dt-consuming"/></p></item></olist></item><item><p>Returning to the outer path expression, the <termref def="dt-posture"/> of the right hand operand <code nobreak="false">child::transaction</code> is
                                 <termref def="dt-striding"/>, and its sweep is <termref def="dt-consuming"/>.</p></item><item><p>So the <termref def="dt-posture"/> of the <code nobreak="false">select</code>
                              expression as a whole is the posture of the right hand operand, that
                              is <termref def="dt-striding"/>; and its sweep is the wider of the
                              sweeps of the operands, which is <termref def="dt-consuming"/>.</p></item></olist></item><item><p>Rule 2 does not apply: there is no <code nobreak="false">group-by</code> attribute.</p></item><item><p>Rule 3 does not apply: there is a <code nobreak="false">group-adjacent</code> attribute, but
                        it is <termref def="dt-motionless"/>. The reasoning is as follows:</p><olist><item><p>The value is a call to the constructor function <code nobreak="false">xs:date</code>.
                              The rules in <specref ref="streamability-of-function-calls"/> apply.
                              There is a single operand, whose required type is atomic, so the
                                 <termref def="dt-operand-usage"/> is <termref def="dt-absorption"/>.</p></item><item><p>These rules refer to the <termref def="dt-general-streamability-rules"/>, so we need to determine the <termref def="dt-context-item-type"/>,
                                 <termref def="dt-posture"/>, and <termref def="dt-sweep"/> of the
                              operand expression <code nobreak="false">@timestamp</code>. This is done as
                              follows:</p><olist><item><p>The expression is an <code nobreak="false">AxisStep</code>, so the relevant
                                    rules are in <specref ref="streamability-of-axis-steps"/>.</p></item><item><p>The <termref def="dt-context-posture"/> is the <termref def="dt-posture"/> of the <termref def="dt-controlling-operand"/> of the <termref def="dt-focus-setting-container"/>, that is, is the
                                       <code nobreak="false">select</code> expression of the containing
                                       <elcode>xsl:for-each-group</elcode> instruction, which as
                                    established above is <termref def="dt-striding"/>. The <termref def="dt-context-item-type"/> is similarly the inferred type
                                    of the <code nobreak="false">select</code> expression, and is
                                       <code nobreak="false">element()</code>.</p></item><item><p>Rules 1 and 2 do not apply because the <termref def="dt-context-posture"/> is <termref def="dt-striding"/>.</p></item><item><p>Rule 3 does not apply because the attribute axis for an element
                                    node is not necessarily empty.</p></item><item><p>Rule 4 does not apply because there is no predicate.</p></item><item><p>So the <termref def="dt-sweep"/> and <termref def="dt-posture"/>
                                    of the expression <code nobreak="false">@timestamp</code> are given by the table
                                    in Rule 5 as <termref def="dt-striding"/> and <termref def="dt-motionless"/>.</p></item></olist></item><item><p>Returning to the <termref def="dt-general-streamability-rules"/> for
                              the expression <code nobreak="false">xs:date(@timestamp)</code>, the operand <code nobreak="false">@timestamp</code>
                              has <var>U</var> = <termref def="dt-absorption"/>, <var>T</var> =
                                 <code nobreak="false">attribute()</code>, <var>P</var> = <termref def="dt-striding"/>, <var>S</var>
                              = <termref def="dt-motionless"/>. </p></item><item><p>Under Rule 1(b)(iii)(A), because <var>T</var> =
                                 <code nobreak="false">attribute()</code>, the <termref def="dt-operand-usage"/>
                              <var>U'</var> becomes <termref def="dt-inspection"/>.</p></item><item><p>Under Rule 1(b)(iii)(A), <var>S'</var> = <var>S</var> = <termref def="dt-motionless"/>.</p></item><item><p>Under Rule 2(e), the expression <code nobreak="false">xs:date(@timestamp)</code> is
                                 <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item></olist></item><item><p>Rule 4 (under <elcode>xsl:for-each-group</elcode>) does not apply, because
                        there is no <elcode>xsl:sort</elcode> child.</p></item><item><p>So Rule 5 applies. This relies on knowing the <termref def="dt-posture"/> of
                        the sequence constructor contained in the
                           <elcode>xsl:for-each-group</elcode> instruction: that is, the <termref def="dt-posture"/> of the <code nobreak="false">total</code>
                        <xtermref spec="XT40" ref="dt-literal-result-element"/>. This is calculated as
                        follows:</p><olist><item><p>The rules that apply are in <specref ref="streamability-literal-result-elements"/>. The <termref def="dt-general-streamability-rules"/> apply; there are two
                              operands, the attribute value templates
                                 <code nobreak="false">{current-grouping-key()}</code> and
                                 <code nobreak="false">{sum(current-group()/@value)}</code>, and in each case the
                              usage is <termref def="dt-absorption"/>. We can simplify the analysis
                              by observing that the empty <xtermref spec="XT40" ref="dt-sequence-constructor"/>
                              contained in the literal result element can be ignored, since it is
                                 <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.
                           </p></item><item><p>Consider first the operand <code nobreak="false">{current-grouping-key()}</code>.</p><olist><item><p>Section <specref ref="classifying-vts"/> applies. This refers to
                                    the <termref def="dt-general-streamability-rules"/>; there is a
                                    single operand, the expression
                                       <code nobreak="false">current-grouping-key()</code>, with usage <termref def="dt-absorption"/>.</p></item><item><p>Section <specref ref="streamability-fn-current-grouping-key"/>
                                    applies. This establishes that the expression is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item><item><p>It follows that the operand
                                       <code nobreak="false">{current-grouping-key()}</code> expression is also
                                       <termref def="dt-grounded"/> and <termref def="dt-motionless"/>.</p></item></olist></item><item><p>Now consider the operand
                              <code nobreak="false">{sum(current-group()/@value)}</code>.</p></item><item><p>Section <specref ref="classifying-vts"/> applies. This refers to the
                                 <termref def="dt-general-streamability-rules"/>; there is a single
                              operand, the expression <code nobreak="false">sum(current-group()/@value)</code>, with
                              usage <termref def="dt-absorption"/>.</p></item><item><p>The rules for the <code nobreak="false">sum</code> function appear in <specref ref="classifying-built-in-functions"/>. The proforma is given there
                              as <code nobreak="false">fn:sum(A)</code>, which means that the <termref def="dt-general-streamability-rules"/> apply, and that the single
                              operand <code nobreak="false">current-group()/@value</code> has usage <termref def="dt-absorption"/>. So we need to establish the <termref def="dt-posture"/>, <termref def="dt-sweep"/>, and type of this
                              expression, which we can do as follows:</p><olist><item><p>The expression is a <code nobreak="false">RelativePathExpr</code>, so section
                                       <specref ref="streamability-of-path-expressions"/>
                                    applies.</p></item><item><p>The expression is expanded to
                                       <code nobreak="false">current-group()/attribute::value</code>.</p></item><item><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                                    the left-hand operand <code nobreak="false">current-group()</code> are defined
                                    in <specref ref="streamability-fn-current-group"/>. Since all
                                    the required conditions are satisfied, the <termref def="dt-posture"/> of <code nobreak="false">current-group()</code> is the
                                       <termref def="dt-posture"/> of the <code nobreak="false">select</code>
                                    expression, that is <termref def="dt-striding"/>, and its
                                       <termref def="dt-sweep"/> is the <termref def="dt-sweep"/> of
                                    the <code nobreak="false">select</code> expression, that is <termref def="dt-consuming"/>.</p></item><item><p>The <termref def="dt-posture"/> and <termref def="dt-sweep"/> of
                                    the right hand operand <code nobreak="false">@value</code> are defined in
                                       <specref ref="streamability-of-axis-steps"/>. The <termref def="dt-context-posture"/> is the <termref def="dt-posture"/>
                                    of the left-hand operand <code nobreak="false">current-group()</code>, namely
                                       <termref def="dt-striding"/>; the table in Rule 5 applies,
                                    giving the result <termref def="dt-climbing"/> and <termref def="dt-motionless"/></p></item><item><p>The <termref def="dt-posture"/> of the
                                       <code nobreak="false">RelativePathExpr</code> is the <termref def="dt-posture"/> of the right hand operand, namely <termref def="dt-striding"/>. The <termref def="dt-sweep"/> of the
                                       <code nobreak="false">RelativePathExpr</code> is the wider of the <termref def="dt-sweep">sweeps</termref> of its operands, which is
                                       <termref def="dt-consuming"/></p></item><item><p>The type of the expression <code nobreak="false">current-group()/@value</code>
                                    is determined using the rules in <specref ref="determining-static-type"/> as
                                    <code nobreak="false">attribute()</code>.</p></item></olist></item><item><p>So the <code nobreak="false">sum</code> function has a single operand with
                                 <var>U</var> = <termref def="dt-absorption"/>, <var>P</var> =
                                 <termref def="dt-striding"/>, <var>S</var> = <termref def="dt-consuming"/>,
                                 <var>T</var> = <code nobreak="false">attribute()</code>.</p></item><item><p>In the <termref def="dt-general-streamability-rules"/>, Rule
                              1(b)(iii)(A) gives the adjusted usage as <var>U'</var> = <termref def="dt-inspection"/>, and Rule 1(b)(iii)(B) gives the adjusted
                              sweep as <var>S'</var> = <var>S</var> = <termref def="dt-consuming"/>.
                              Rule 2(d) gives the posture and sweep of the call to <code nobreak="false">sum</code>
                              as <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.
                           </p></item></olist></item><item><p>So the literal result element has two operands, one of which is <termref def="dt-grounded"/> and <termref def="dt-motionless"/>, the other
                           <termref def="dt-grounded"/> and <termref def="dt-consuming"/>. Rule 2(d)
                        of the <termref def="dt-general-streamability-rules"/> determines that the
                        literal result element is <termref def="dt-grounded"/> and <termref def="dt-consuming"/>.</p></item><item><p>So the content of the <elcode>xsl:source-document</elcode> instruction is <termref def="dt-grounded"/>, which means that the instruction is <termref def="dt-guaranteed-streamable"/>.</p></item></olist></example></div2><div2 id="streamability-with-1.0"><head>Streamability and 1.0 Compatibility Mode</head><p>Processing an <xtermref spec="XT40" ref="dt-instruction"/> with XSLT
                  1.0 behavior is not compatible with streaming. More specifically, and
                  notwithstanding anything stated in <specref ref="streamability"/>, an instruction
                  that is processed with XSLT 1.0 behavior is <termref def="dt-roaming"/> and
                     <termref def="dt-free-ranging"/>, which has the effect that any construct
                  containing such an instruction is not <termref def="dt-guaranteed-streamable"/>.</p></div2></div1><div1 id="conformance"><head>Conformance</head><p>
               <termdef id="dt-streaming-feature" term="streaming feature">A processor that claims
                  conformance with the <term>streaming feature</term>
                  <rfc2119>must</rfc2119> use streamed processing in cases where (a) streaming is
                  requested (for example by using the attribute <code nobreak="false">streamable="yes"</code> on
                  <elcode>xsl:mode</elcode>, or on
                  the <elcode>xsl:source-document</elcode> instruction) and
                  (b) the constructs in question are <termref def="dt-guaranteed-streamable"/>
                  according to this specification.</termdef>
            </p><p>A processor that does not claim conformance with the streaming feature is not
               required to use streamed processing and is not required to determine whether any
               construct is guaranteed streamable. Such a processor must, however, implement the
               semantics of all constructs in the language provided that enough memory is available
               to perform the processing without streaming.</p><p>A processor that conforms with the feature <rfc2119>must</rfc2119>
               return the value <code nobreak="false">"yes"</code> in response to the function call
                  <code nobreak="false">system-property('xsl:supports-streaming')</code>; a processor that does not
               conform with the feature <rfc2119>must</rfc2119> return the value
               <code nobreak="false">"no"</code>.</p><note><p>The term <emph>streamed processing</emph> as used here means the ability to
                  process arbitrarily large input documents without ever-increasing memory
                  requirements.</p></note></div1></body><back><div1 id="references"><head>References</head><div2 id="normative-references"><head>Normative References</head><blist><!--<bibl id="xpath-datamodel-30" key="XDM 3.0"/>
               <bibl id="xpath-datamodel-31" key="XDM 3.1"/>--><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">
                 <emph>CITATION: T.B.D.</emph>
               </bibl><!--World Wide Web Consortium. 
<emph>XQuery 1.0 and XPath 2.0 Functions and Operators.</emph>
W3C Working Draft. ute
See <loc href="http://www.w3.org/TR/xpath-functions/"/>
					</bibl>--><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml-infoset" key="XML Information Set" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><!--World Wide Web Consortium. 
					<emph>XML Information Set.</emph> W3C Recommendation. 
					See <loc href="http://www.w3.org/TR/xml-infoset/"/>
                    </bibl>--><!--<bibl id="ISO3166" key="ISO 3166-1">ISO (International Organization for
                  Standardization) <emph>Codes for the representation of names of countries and
                  their subdivisions - Part 1: Country codes</emph> ISO 3166-1:1997. 
                  Second edition, 2006-11-20. </bibl>--><!--<bibl id="ISO8601" key="ISO 8601">ISO (International Organization for
                  Standardization) <emph>Data elements and interchange formats - Information
                     interchange - Representation of dates and times.</emph> ISO 8601:2004,
                     Third edition, 2004-12-03. </bibl>--><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO15924" key="ISO 15924" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ISO (International Organization for
                  Standardization) <emph>Information and documentation — Codes for the
                     representation of names of scripts</emph> ISO 15924:2004, January 2004. See <loc href="https://www.iso.org/obp/ui/#!iso:std:iso:15924:ed-1:v1:en" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO15924_register" key="ISO 15924 Register" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Unicode Consortium. <emph>Codes
                     for the representation of names of scripts — Alphabetical list of
                     four-letter script codes.</emph> See <loc href="http://www.unicode.org/iso15924/iso15924-codes.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>. Retrieved
                  February 2013; continually updated.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO21320" key="ISO 21320" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ISO (International Organization for
                  Standardization) <emph>Information technology — Document Container File, Part 1: Core</emph> 
                  ISO 21320-1:2015, October 2015. See <loc href="https://www.iso.org/obp/ui/#iso:std:iso-iec:21320:-1:ed-1:v1:en" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</bibl><!--<bibl id="xslt-xquery-serialization-40" key="XSLT and XQuery Serialization"/>
               <bibl id="xslt-xquery-serialization-31" key="XSLT and XQuery Serialization 3.1"/>--><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="UNICODE-NORMALIZATION" key="Unicode Normalization">Unicode Consortium.
					<emph>Unicode Normalization Forms</emph>. Unicode Standard Annex #15.
					See <loc href="http://www.unicode.org/unicode/reports/tr15/"/>
					</bibl>--><!--					<bibl id="XHTML10" key="XHTML 1.0">World Wide Web Consortium. <emph>XHTML
1.0: The Extensible HyperText Markup Language.</emph> W3C Recommendation. 
See <loc href="http://www.w3.org/TR/xhtml1/"/>. Note: a second edition of this
specification is in preparation.</bibl>--><!--					<bibl id="XHTML11" key="XHTML 1.1">World Wide Web Consortium. <emph>XHTML
1.1: Module-Based XHTML.</emph> W3C Recommendation. 
See <loc href="http://www.w3.org/TR/xhtml11/"/>
</bibl>--><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc7595" key="RFC 7595" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>Guidelines and Registration Procedures for URI Schemes.</emph>
                  June 2015. See <loc href="http://www.ietf.org/rfc/rfc7595.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc7595.txt</loc>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc7159" key="RFC 7159" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>The JavaScript Object Notation (JSON)
                     Data Interchange Format.</emph>
                  March 2014. See <loc href="http://www.ietf.org/rfc/rfc7159.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc7159.txt</loc>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="UNICODE" key="UNICODE" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Unicode Consortium. <emph>The Unicode
                     Standard</emph> as updated from time to time by the publication of new
                  versions. See <loc href="http://www.unicode.org/standard/versions/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/> 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="UNICODE-TR10" key="UNICODE TR10" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Unicode Consortium. <emph>Unicode
                     Technical Standard #10. Unicode Collation Algorithm</emph>. Unicode Technical
                  Report. See <loc href="http://www.unicode.org/reports/tr10/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="UNICODE-TR35" key="UNICODE TR35" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Unicode Consortium. <emph>Unicode
                     Technical Standard #35. Unicode Locale Data Markup Language</emph>. Unicode
                  Technical Report. See <loc href="http://www.unicode.org/reports/tr35/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="REC-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. W3C Recommendation.</emph> See <loc href="https://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"/>, but we recommend that
                  implementations use the latest version. </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml11" key="XML 1.1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlbase" key="XML Base" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml-id" key="xml:id" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml-names" key="Namespaces in XML" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml-names11" key="Namespaces in XML 1.1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema-1" key="XML Schema Part 1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema-2" key="XML Schema Part 2" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema11-1" key="XML Schema 1.1 Part 1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema11-2" key="XML Schema 1.1 Part 2" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath-40" key="XPath 4.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                 <emph>CITATION: T.B.D.</emph>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="XSLT-Mime-Type" key="XSLT Media Type" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">World Wide Web Consortium.
                     <emph>Registration of MIME Media Type application/xslt+xml</emph>. In <loc href="https://www.w3.org/TR/2007/REC-xslt20-20070123/#media-type-registration" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Appendix B.1 of the XSLT 2.0 specification.</loc></bibl></blist></div2><div2 id="other-references"><head>Other References</head><blist><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="CLDR" key="Unicode CLDR" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">CLDR - Unicode Common Locale Data Repository.
                  Available at: <loc href="http://cldr.unicode.org" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://cldr.unicode.org</loc></bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="DOM-Level-2-Core" key="DOM Level 2" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ECMA-404" key="ECMA-404" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> ECMA International. <emph>The JSON Data
                     Interchange Format</emph> October 2013. See <loc href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf</loc>. </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ICU" key="ICU" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ICU - International Components for Unicode. Available at
                     <loc href="http://site.icu-project.org" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://site.icu-project.org</loc>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="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"/>.</bibl><!--<bibl id="RFC2376" key="RFC2376">E. Whitehead, M. Murata. <emph>XML Media
                     Types</emph>. IETF RFC 2376. See <loc
                     href="http://www.ietf.org/rfc/rfc2376.txt"/>.</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"/>.</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, 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"/>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="RFC4647" key="RFC4647" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">A. Phillips and M. Davis. <emph>Matching of Language Tags</emph>. IETF RFC 4647. See <loc href="http://www.ietf.org/rfc/rfc4647.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc7303" key="RFC7303" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">H. Thompson and C. Lilley. <emph>XML Media
                     Types</emph>. IETF RFC 7303. See <loc href="http://www.ietf.org/rfc/rfc7303.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/></bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="SemVer" key="SemVer" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Tom Preston-Werner, <emph>Semantic Versioning
                     2.0.0</emph>. See <loc href="http://semver.org/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>. Undated (retrieved 1 August
                  2014).</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="STX" key="STX" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Petr Cimprich <emph>et al</emph>, <emph>Streaming
                     Transformations for XML (STX) Version 1.0</emph>. Working Draft 27 April 2007.
                  See <loc href="http://stx.sourceforge.net/documents/spec-stx-20070427.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
               </bibl><!--<bibl id="xinclude" key="XInclude"/>--><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xlink" key="XLink" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="SCHEMA-AND-XML-1.1" key="XML Schema 1.0 and XML 1.1" 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="https://www.w3.org/TR/2005/NOTE-xml11schema10-20050511/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml-stylesheet" key="XML Stylesheet" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xptr-framework" key="XPointer Framework" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xsl11" key="XSL-FO" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xslt" key="XSLT 1.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xslt20" key="XSLT 2.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xslt-30" key="XSLT 3.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><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"/></blist></div2></div1><inform-div1 id="error-summary"><head>Summary of Error Conditions</head><p>This appendix provides a summary of error conditions that a processor
            may raise. This list includes all error codes defined in this specification, but this
            is not an exhaustive list of all errors that can occur. Implementations
               <rfc2119>must</rfc2119> raise errors using these error codes, and applications can
            test for these codes; however, when more than one rule in the specification is violated,
            different processors will not necessarily raise the same error code. Implementations
            are not <rfc2119>required</rfc2119> to raise errors using the descriptive text used
            here.</p><note><p>The appendix is non-normative because the same information is given normatively
               elsewhere.</p></note><?error-summary?></inform-div1><inform-div1 id="revision-log"><head>Change Log</head><p>This appendix lists changes made in version 4.0 of this specification.</p><?change-log?></inform-div1></back></spec><!--XSLT Processor: Saxonica-->