Docunext


Circular Processing with XSL

December 9th, 2009

The idea is to feed the output of a stylesheet back into itself, but how can the process be managed, not infinite?

Andrew Welch suggests:

You can do all the transformations in your pipeline in one stylesheet by performing transformations within variables, with each variable operating on the previous one.

So, as top-level variables you could have:

<xsl:variable name="firstVar-rtf">

<xsl:apply-templates/>

</xsl:variable>

<xsl:variable name="firstVar" select="exsl:node-set($firstVar-rtf)"/>

<xsl:variable name="secondVar-rtf">

<xsl:for-each select="$firstVar">

&lt;xsl:apply-templates/>

</xsl:for-each>

</xsl:variable>

<xsl:variable name="secondVar" select="exsl:nodet-set($secondVar-rtf)"/>

Here $firstVar operates on the source xml, and $secondVar works on the 'result' of the apply-templates in $firstVar.

The final link in the chain is of course:

<xsl:template match="/">

<xsl:for-each select="$lastVar">

&lt;xsl:apply-templates/>

</xsl:for-each>

</xsl:template>

All you need to do is separate out your problem into logical steps and perform each one in a varaible.

I do this a lot when xslt 1.0 struggles to do a task in one go, such as finding the average of two percentages written as 45% and 55%.

The first variable would translate() the '%' away, the second variable would find the average.

Dimitre notes:

This will select just the root node (/) of the temporary tree contained in $firstVar

Must be:

&lt;xsl:for-each select="$firstVar/node()">
&lt;xsl:apply-templates/>

</xsl:for-each>

</xsl:variable>

<xsl:variable name="secondVar" select="exsl:nodet-set($secondVar-rtf)"/>

Here $firstVar operates on the source xml, and $secondVar works on the

'result' of the apply-templates in $firstVar.

The final link in the chain is of course:

<xsl:template match="/">

<xsl:for-each select="$lastVar">

The same problem:

Must be:

&lt;xsl:for-each select="$lastVar/node()">

Dimitre Novatchev.

I'm busy trying to figure this out....

Didn't do what I wanted it to, but I did learn something.

<xsl:variable name="firstVar-rtf">
  First
  <xsl:apply-templates />
</xsl:variable>
<xsl:variable name="firstVar" select="exsl:node-set($firstVar-rtf)"/>

<xsl:variable name="secVar-rtf">
Second
  <xsl:for-each select="$firstVar/node()">
    <xsl:copy-of select="."/>
    <xsl:apply-templates />
  </xsl:for-each>
</xsl:variable>
<xsl:variable name="secVar" select="exsl:node-set($secVar-rtf)"/>

<xsl:variable name="tripVar-rtf">
Third
  <xsl:for-each select="$secVar/node()">
    <xsl:copy-of select="."/>
    <xsl:apply-templates />
  </xsl:for-each>
</xsl:variable>
<xsl:variable name="tripVar" select="exsl:node-set($tripVar-rtf)"/>

<xsl:template match="/">
<div>
  <xsl:for-each select="$tripVar/node()">

    <xsl:copy-of select="."/>
    <xsl:if test="name()='h2'">
    skdlj
    </xsl:if>

    lakjdfkj
  </xsl:for-each>
  </div>
</xsl:template>
Yearly Indexes: 2003 2004 2006 2007 2008 2009 2010 2011 2012 2013 2015 2019 2020 2022