SAXONICA

Saxon Documentation
Full Contents
About Saxon
Changes in this Release
Notices
Using XSLT 2.0
Using XQuery
Handling Source Documents
| Handling Source Documents
| Source Documents on the Command Line
| Collections
| Building a Source Document from an application
| Preloading shared reference documents
| Writing input filters
| XInclude processing
| Saxon and XML 1.1
| JAXP Source Types
| Third-party Object Models: DOM, JDOM, XOM, and DOM4J
| Choosing a Tree Model
| The PTree File Format
| Validation of Source Documents
| Whitespace Stripping in Source Documents
» | Streaming of Large Documents
| Document Projection
XML Schema Processing
XPath API for Java
Saxon on .NET
Extensibility
Saxon Extensions
Sample Saxon Applications
The Saxon SQL Extension
XSLT Elements
XPath 2.0 Expression Syntax
Function Library
Standards Conformance

# Using saxon:stream() with saxon:iterate

In the examples given above, `saxon:stream()` 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 `saxon:stream()` in conjunction with the `saxon:iterate` extension element in XSLT. (For details see saxon:iterate.)

The following example takes a sequence of `<transaction>` 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.

          <saxon:iterate select="saxon:stream(doc('transactions.xml')/account/transaction)">
            <xsl:param name="balance" as="xs:decimal" select="0.00"/>
            <xsl:variable name="new-balance" as="xs:decimal" select="$balance + xs:decimal(@value)"/>
            <transaction balance="{$new-balance}">
               <xsl:copy-of select="@*"/>
            </transaction>
            <saxon:continue>
              <xsl:with-param name="balance" select="$new-balance"/>
            </saxon:continue>
          </saxon:iterate>

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:

          <saxon:iterate select="saxon:stream(doc('transactions.xml')/account/(account-number|transaction))">
            <xsl:param name="accountNr"/>
            <xsl:choose>
               <xsl:when test="self::account-number">
                 <saxon:continue>
                    <xsl:with-param name="accountNr" select="string(.)"/>
                 </saxon:continue>
               </xsl:when>
               <xsl:otherwise>
                 <transaction account-number="{$accountNr}">
                   <xsl:copy-of select="@*"/>
                 </transaction>
               </xsl:otherwise>
            </xsl:choose>
          </saxon:iterate>

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.

          <saxon:iterate select="saxon:stream(doc('transactions.xml')/account/transaction)">
          <xsl:param name="group" as="element(transaction)*" select="()"/>
          <xsl:param name="currentDate" as="xs:date?" select="()"/>
            <xsl:choose>
              <xsl:when test="xs:date(@date) eq $currentDate or empty($group)">
                <saxon:continue>
                  <xsl:with-param name="currentDate" select="@date"/>
                  <xsl:with-param name="group" select="($group, .)"/>
                </saxon:continue>
              </xsl:when>
              <xsl:otherwise>
                <daily-transactions date="{$currentDate}">
                  <xsl:copy-of select="$group"/>
                </daily-transactions>
                <saxon:continue>
                  <xsl:with-param name="group" select="."/>
                  <xsl:with-param name="currentDate" select="@date"/>
                </saxon:continue>
              </xsl:otherwise>
            </xsl:choose>
            <saxon:finally>
              <final-daily-transactions date="{$currentDate}">
                <xsl:copy-of select="$group"/>
              </final-daily-transactions>
            </saxon:finally>
          </saxon:iterate>

Note that when a `saxon:iterate` loop is terminated using `saxon:break`, 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.

Next