<?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="streamwithiterate"/>
      <!--
           Generated at 2010-10-29T18:20:48.427+01:00--><title>Saxonica: XSLT and XQuery Processing: Using saxon:stream() with saxon:iterate</title>
      <meta name="coverage" content="Worldwide"/>
      <meta name="copyright" content="Copyright Saxonica Ltd"/>
      <meta name="title"
            content="Saxonica: XSLT and XQuery Processing: Using saxon:stream() with saxon:iterate"/>
      <meta name="robots" content="noindex,nofollow"/>
      <link rel="stylesheet" href="../../saxondocs.css" type="text/css"/>
   </head>
   <body class="main">
      <h1>Using saxon:stream() with saxon:iterate</h1>
      <p>In the examples given above, <code>saxon:stream()</code> is used to select a sequence of element nodes
from the source document, and each of these nodes is then processed independently. In cases where the processing
of one node depends in some way on previous nodes, it is possible to use <code>saxon:stream()</code> in 
conjunction with the <code>saxon:iterate</code> extension element in XSLT.  
(For details see <a class="bodylink" href="../../extensions/instructions/iterate.xml">saxon:iterate</a>.)</p>
      <p>The following example takes a sequence of <code>&lt;transaction&gt;</code> elements in an input document, each one containing
the value of a debit or credit from an account. As output it copies the transaction elements, adding a current balance.</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>
      &lt;saxon:iterate select="saxon:stream(doc('transactions.xml')/account/transaction)"&gt;
        &lt;xsl:param name="balance" as="xs:decimal" select="0.00"/&gt;
        &lt;xsl:variable name="new-balance" as="xs:decimal" select="$balance + xs:decimal(@value)"/&gt;
        &lt;transaction balance="{$new-balance}"&gt;
           &lt;xsl:copy-of select="@*"/&gt;
        &lt;/transaction&gt;
        &lt;saxon:continue&gt;
          &lt;xsl:with-param name="balance" select="$new-balance"/&gt;
        &lt;/saxon:continue&gt;
      &lt;/saxon:iterate&gt;
</code>
         </pre>
      </div>
      <p>The following example is similar: this time it copies the account number (contained in a separate element
at the start of the file) into each transaction element:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>
      &lt;saxon:iterate select="saxon:stream(doc('transactions.xml')/account/(account-number|transaction))"&gt;
        &lt;xsl:param name="accountNr"/&gt;
        &lt;xsl:choose&gt;
           &lt;xsl:when test="self::account-number"&gt;
             &lt;saxon:continue&gt;
                &lt;xsl:with-param name="accountNr" select="string(.)"/&gt;
             &lt;/saxon:continue&gt;
           &lt;/xsl:when&gt;
           &lt;xsl:otherwise&gt;
             &lt;transaction account-number="{$accountNr}"&gt;
               &lt;xsl:copy-of select="@*"/&gt;
             &lt;/transaction&gt;
           &lt;/xsl:otherwise&gt;
        &lt;/xsl:choose&gt;
      &lt;/saxon:iterate&gt;
</code>
         </pre>
      </div>
      <p>Here is a more complex example, one that groups adjacent transaction elements having the same
date attribute. The two loop parameters are the current grouping key and the current date. The contents
of a group are accumulated in a variable until the date changes.</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>
      &lt;saxon:iterate select="saxon:stream(doc('transactions.xml')/account/transaction)"&gt;
      &lt;xsl:param name="group" as="element(transaction)*" select="()"/&gt;
      &lt;xsl:param name="currentDate" as="xs:date?" select="()"/&gt;
        &lt;xsl:choose&gt;
          &lt;xsl:when test="xs:date(@date) eq $currentDate or empty($group)"&gt;
            &lt;saxon:continue&gt;
              &lt;xsl:with-param name="currentDate" select="@date"/&gt;
              &lt;xsl:with-param name="group" select="($group, .)"/&gt;
            &lt;/saxon:continue&gt;
          &lt;/xsl:when&gt;
          &lt;xsl:otherwise&gt;
            &lt;daily-transactions date="{$currentDate}"&gt;
              &lt;xsl:copy-of select="$group"/&gt;
            &lt;/daily-transactions&gt;
            &lt;saxon:continue&gt;
              &lt;xsl:with-param name="group" select="."/&gt;
              &lt;xsl:with-param name="currentDate" select="@date"/&gt;
            &lt;/saxon:continue&gt;            
          &lt;/xsl:otherwise&gt;
        &lt;/xsl:choose&gt;
        &lt;saxon:finally&gt;
          &lt;final-daily-transactions date="{$currentDate}"&gt;
            &lt;xsl:copy-of select="$group"/&gt;
          &lt;/final-daily-transactions&gt;
        &lt;/saxon:finally&gt;        
      &lt;/saxon:iterate&gt;
</code>
         </pre>
      </div>
      <p>Note that when a <code>saxon:iterate</code> loop is terminated using <code>saxon:break</code>,
parsing of the source document will be abandoned. This provides a convenient way to read data near the start
of a large file without incurring the cost of reading the entire file.</p>
      <table width="100%">
         <tr>
            <td>
               <p align="right"><a class="nav" href="streaming-templates.xml">Next</a></p>
            </td>
         </tr>
      </table>
   </body>
</html>