Re: [xsl] How to do this without updating a variable?

Subject: Re: [xsl] How to do this without updating a variable?
From: "Jay Bryant" <jay@xxxxxxxxxxxx>
Date: Wed, 7 Sep 2005 17:59:58 -0500
And here are two other ways (the first of which Antonio sketched earlier):

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:template match="/">
    <html>
      <body>
        <table border="1">
          <tr>
            <th>Node</th><th>Start</th><th>End</th>
          </tr>
          <xsl:apply-templates/>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="a">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="reg">
    <xsl:choose>
      <xsl:when test="position() = 1">
        <tr>
          <td><xsl:value-of select="."/></td><td>1</td><td><xsl:value-of
select="@count"/></td>
        </tr>
      </xsl:when>
      <xsl:otherwise>
        <tr>
          <td><xsl:value-of select="."/></td><td><xsl:value-of
select="sum(preceding::reg/@count) + 1"/></td><td><xsl:value-of
select="sum(preceding::reg/@count) + @count"/></td>
        </tr>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

And next:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:variable name="regs">
    <xsl:for-each select="//reg">
      <xsl:copy-of select="."/>
    </xsl:for-each>
  </xsl:variable>

  <xsl:template match="/">
    <html>
      <body>
        <table border="1">
          <tr>
            <th>Node</th><th>Start</th><th>End</th>
          </tr>
          <xsl:for-each select="$regs//reg">
            <xsl:choose>
              <xsl:when test="position() = 1">
                <tr>
                  <td><xsl:value-of
select="."/></td><td>1</td><td><xsl:value-of select="@count"/></td>
                </tr>
              </xsl:when>
              <xsl:otherwise>
                <tr>
                  <td><xsl:value-of select="."/></td><td><xsl:value-of
select="sum(preceding::reg/@count) + 1"/></td><td><xsl:value-of
select="sum(preceding::reg/@count) + @count"/></td>
                </tr>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

I tested all three with Saxon 8 (though nothing here requires an XSLT 2.0
processor).

Note that the choose block is the same in all three methods.

Which of the three is best depends on your XML file. If you need to gather
elements from all over the place (different parent elements and different
depths), gathering them into a variable can be a big help.

I'm sure there are still other ways, too. Thinking about things being
scattered through the input sets me to thinking about keys....

Jay Bryant
Bryant Communication Services

Current Thread