<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="../../make-menu.xsl" type="text/xsl"?><html>
   <head>
      <this-is section="sourcedocs" page="streaming" subpage="streaming-templates"/>
      <!--
           Generated at 2011-12-09T20:47:22.916Z--><title>Saxonica: XSLT and XQuery Processing: Streaming Templates</title>
      <meta name="coverage" content="Worldwide"/>
      <meta name="copyright" content="Copyright Saxonica Ltd"/>
      <meta name="title"
            content="Saxonica: XSLT and XQuery Processing: Streaming Templates"/>
      <meta name="robots" content="noindex,nofollow"/>
      <link rel="stylesheet" href="../../saxondocs.css" type="text/css"/>
   </head>
   <body class="main">
      <h1>Streaming Templates</h1>
      <p>Streaming templates allow a document to be processed hierarchically in the classical XSLT style, applying
template rules to each element (or other nodes) in a top-down manner, while scanning the source document in a pure
streaming fashion, without building the source tree in memory. Saxon-EE allows
streamed processing of a document using template rules, provided the templates conform to a set of strict guidelines.
         The facility was introduced in a very simple form in Saxon 9.2, and is greatly enhanced in Saxon 9.3.</p>
      <p>Streaming is a property of a <b>mode</b>; a mode can be declared to be streamable, and if it is so declared, then
all template rules using that mode must obey the rules for streamability. A mode is declared to be streamable using
the top-level stylesheet declaration:</p>
      <p class="command">&lt;xsl:mode name="s" streamable="yes"/&gt;</p>
      <p>The <code>name</code> attribute is optional; if omitted, the declaration applies to the default (unnamed) mode.</p>
      <p>Streamed processing of a source document can be applied either to the principal source document of the transformation,
or to a secondary source document read using the <code>doc()</code> or <code>document()</code> function.</p>
      <p>To use streaming on the principal source document, the input to the transformation must be supplied in the form of a
<code>StreamSource</code> or <code>SAXSource</code>, and the initial mode selected on entry to the transformation must be
a streamable mode. In this case there must be no references to the context item in the initializer of any global variable.</p>
      <p>Streamed processing of a secondary document is initiated using the instruction:</p>
      <p class="command">&lt;xsl:apply-templates select="doc('abc.xml')" mode="s"/&gt;</p>
      <p>Here the <code>select</code> attribute must contain a simple call on the <code>doc()</code> or <code>document()</code>
function, and the mode (explicit or implicit) must be declared as streamable. The call on <code>doc()</code> or <code>document()</code>
         can be extended with a streamable selection path, for example <code>select="doc('employee.xml')/*/employee"</code></p>
      <p>If a mode is declared as streamable, then it must ONLY be used in streaming mode; it is not possible to apply templates
using a streaming mode if the selected nodes are ordinary non-streamed nodes. </p>
      <p>Every template rule within a streamable mode must follow strict rules to ensure it can be processed in a streaming manner. The
               essence of these rules is:</p>
      <ol>
         <li>
            <p>The match pattern for the template rule must be a simple pattern that can be evaluated
                  when positioned at the start tag of an element, without repositioning the stream (but information about the ancestors
                  of the element and their attribute is available). Examples of acceptable patterns are <code>*</code>, <code>para</code>, or <code>para/*</code></p>
         </li>
         <li>
            <p>
                  The body of the template rule must contain at most one expression or instruction that reads the contents below the matched element
                  (that is, children or descendants),
                  and it must process the contents in document order. This expression or instruction will often be one of the following:</p>
            <ul>
               <li>
                  <p><code>&lt;xsl:apply-templates/&gt;</code></p>
               </li>
               <li>
                  <p><code>&lt;xsl:value-of select="."/&gt;</code></p>
               </li>
               <li>
                  <p><code>&lt;xsl:copy-of select="."/&gt;</code></p>
               </li>
               <li>
                  <p><code>string(.)</code></p>
               </li>
               <li>
                  <p><code>data(.)</code> (explicitly or implicitly)</p>
               </li>
            </ul>
            <p>but this list is not exhaustive. It is possible to process the contents selectively by using a streamable path expression,
                  for example:</p>
            <ul>
               <li>
                  <p><code>&lt;xsl:apply-templates select="foo"/&gt;</code></p>
               </li>
               <li>
                  <p><code>&lt;xsl:value-of select="a/b/c"/&gt;</code></p>
               </li>
               <li>
                  <p><code>&lt;xsl:copy-of select="x/y"/&gt;</code></p>
               </li>
            </ul>
            <p>but this effectively means that the content not selected by this path is skipped entirely; the transformation ignores it.</p>
            <p>The template can access attributes of the context item without restriction, as well as properties such as its <code>name()</code>,
                        <code>local-name()</code>, and <code>base-uri()</code>. It can also access the ancestors of the context item, the attributes
                        of the ancestors, and properties such as the name of an ancestor; but having navigated to an ancestor, it cannot then navigate
                        downwards or sideways, since the siblings and the other descendants of the ancestor are not available while streaming.</p>
            <p>The restriction that only one downwards access is allowed makes it an error to use an expression such as
                        <code>price - discount</code> in a streamable template. This problem can often be circumvented by making a copy of the context
                        item. This can be done using an <code>xsl:variable</code> containing an <code>xsl:copy-of</code> instruction, or for convenience
                        it can also be done using the <code>copy-of()</code> function: for example <code>&lt;xsl:value-of select="copy-of(.)/(price - discount)"/&gt;</code>.
                        Taking a copy of the context node requires memory, of course, and should be avoided unless the contents of the node are small.</p>
         </li>
      </ol>
      <p>The following rules gives further advice on what is allowed and disallowed within the body of a streaming template.</p>
      <p class="subhead">Non-context-sensitive instructions</p>
      <p>Instructions and expressions that do not access the context node are allowed without restriction.</p>
      <p>This includes:</p>
      <ul>
         <li>
            <p>Instructions that create new nodes, for example
            literal result elements, <code>xsl:element</code> and <code>xsl:attribute</code>
            are allowed without restriction.</p>
         </li>
         <li>
            <p>Instructions that declare variables, including temporary trees, if the value of the variable
            does not depend on the context.</p>
         </li>
         <li>
            <p>Instructions that process documents other than the streamed document, for example by calling the
            <code>doc()</code> or <code>document()</code> functions. Provided such processing is not streamed, the full
            capabilities of the XSLT language can be used.</p>
         </li>
      </ul>
      <p class="subhead">Access to attributes and ancestors</p>
      <p>Access to attributes: there are no restrictions on accessing attributes of the
            context node, or attributes of its ancestors.</p>
      <p>Properties of the context node: there are no restrictions on using functions
                  such as <code>name()</code>, <code>node-name()</code>, or <code>base-uri()</code>
                  to access properties of the context node, or properties of its ancestors, its attributes,
                  or attributes of its ancestors.
               It is also possible to use the <code>is</code> operator to test the identity
            of the node, the <code>&lt;&lt;</code> and <code>&gt;&gt;</code> operators to test its
            position in document order, or the <code>instance of</code> operator to test its type.
            For attribute nodes it is possible to use (explicitly or implicitly) the <code>string()</code>
            function to get its string value and the <code>data()</code> function to get its typed value.</p>
      <p>It is not possible to perform navigation from the attributes of the node or from its ancestors, only
            to access the values of attributes and properties such as the name of the node.</p>
      <p>It is not possible to bind a variable (or pass a parameter, or return a result) to
            a node in the streamed document, because Saxon does not currently include the logic to analyse
            that the way in which the variable is subsequently used is consistent with streaming.</p>
      <p class="subhead">Conditional instructions</p>
      <p>This includes <code>xsl:if</code>, <code>xsl:choose</code>, and the XPath <code>if</code> expression.
            All of these are regarded as special cases of a construct of the form <code>if (condition-1) then action-1 else
            if (condition-2) then action2 else ...</code></p>
      <p>The rule is that the conditional must fit one of the following descriptions:</p>
      <ul>
         <li>
            <p>The first condition makes a downward selection, in which case none of the actions and none of the subsequent conditions
                  may make a downward selection</p>
         </li>
         <li>
            <p>The first condition makes no downward selection, in which case each of the actions is allowed to make a downward 
                        selection (but subsequent conditions must not do so).</p>
         </li>
      </ul>
      <p>So examples of permitted conditionals are:</p>
      <ul>
         <li>
            <p><code>if (@a = 3) then b else c</code></p>
         </li>
         <li>
            <p><code>if (a = 3) then @b else @c</code></p>
         </li>
      </ul>
      <p>while the following are not permitted:</p>
      <ul>
         <li>
            <p><code>if (a = 3) then b else c</code></p>
         </li>
         <li>
            <p><code>
&lt;xsl:choose&gt;
   &lt;xsl:when test="a=3"&gt;foo&lt;/xsl:when&gt;
   &lt;xsl:when test="a=4"&gt;bar&lt;/xsl:when&gt;
&lt;/xsl:choose&gt;</code></p>
         </li>
      </ul>
      <p class="subhead">Looping instructions</p>
      <p>This applies primarily to <code>xsl:for-each</code> and <code>xsl:iterate</code>. In addition,
            an XPath expression <code>for $x in SEQ return E</code> is translated to an equivalent <code>xsl:for-each</code>
            instruction, provided that <code>E</code> does not depend on the context item, position, or size.</p>
      <p>The common case is where the <code>select</code> expression and the loop body each make a downward selection,
            for example:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>
&lt;xsl:for-each select="employee"&gt;
  &lt;salary&gt;&lt;xsl:value-of select="salary"/&gt;&lt;/salary&gt;
&lt;/xsl:for-each&gt;</code>
         </pre>
      </div>
      <p>The body of the loop may only make a single downwards selection of this kind.</p>
      <p>No sorting is allowed.</p>
      <p>If the <code>select</code> expression does not make a downward selection, then the loop body must not perform any navigation
            from the context node. This is because the same navigation would have to take place more than once, which is inconsistent with streaming.</p>
      <p>Saxon handles the case where some reordering of the output is required. This arises when the <code>select</code> expression uses the 
            descandant axis, for example:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>
&lt;xsl:for-each select=".//section"&gt;
  &lt;size&gt;&lt;xsl:value-of select="string-length(.)"/&gt;&lt;/size&gt;
&lt;/xsl:for-each&gt;</code>
         </pre>
      </div>
      <p>In this example, given nested sections, the downward selections for each section needed to evaluate <code>string-length()</code>
            overlap with each other, and the string-length of section 2.1 (say) must be output before that of its children (sections 2.1.1 and 2.1.2, say),
            even though the computation for the children completes earlier. Saxon achieves this by buffering output results where necessary to achieve
            the correct ordering.</p>
      <p>It is of course quite permissible to call <code>xsl:apply-templates</code> within the body of the <code>xsl:for-each</code>; this will count
            as the one permitted downward selection.</p>
      <p>It is permitted to call <code>position()</code> within the loop, but not <code>last()</code>.</p>
      <p class="subhead">Sorting, grouping and numbering</p>
      <p>Sorting (<code>xsl:sort</code>), grouping (<code>xsl:for-each-group</code>), and numbering (<code>xsl:number</code>) are not supported in streaming mode.</p>
      <table width="100%">
         <tr>
            <td>
               <p align="right"><a class="nav" href="../projection.xml">Next</a></p>
            </td>
         </tr>
      </table>
   </body>
</html>