You only need to use the variable in the initial <xsl:apply-templates select="$phase-1-result" mode="phase-2" />
. After that you're "inside" the phase 1 result tree, and the match expressions and further selects don't need to use the variable, they just work within this new context:
<xsl:template match="/">
<xsl:variable name="phase-1-result">
<xsl:apply-templates select="/" mode="phase-1"/>
</xsl:variable>
<TABLE border="1">
<xsl:apply-templates mode="phase-2"
select="($phase-1-result/ListOfLabels/Label)[position() mod 3 = 1]"/>
</TABLE>
</xsl:template>
<!-- phase-1 template as before -->
<xsl:template match="Label" mode="phase-2">
<TR>
<xsl:apply-templates select=".|following-sibling::Label[position() lt 3]"
mode="columns" />
</TR>
</xsl:template>
<xsl:template match="Label" mode="columns">
<TD>
<xsl:value-of select="." />
</TD>
</xsl:template>
Here I'm doing the "select every third Label" logic at the point of applying the phase-2
template, so that template only needs to concern itself with the "me and my next two siblings" bit.
It's no different from declaring a variable containing nodes from the original input tree and then applying templates to those
<xsl:variable name="someNodes" select="/foo/bar | /foo/ping" />
<xsl:apply-templates select="$someNodes" />
<xsl:template match="bar">...</xsl:template>
The template match expressions don't care where the nodes came from, they only care what the nodes look like (is it a bar
or a ping
).