Best approach for combining several XSLT 1.0 passes which process the same nodes

I'm doing some very complex XSLT 1.0 transformation (currently using 8 XSLT passes). I want to combine this 8 passes without merging them in one file (this would be too complex). My solution would be using xsl:include and exsl:node-set to merge the passes and store temporary results in variables.

But I have one problem: My transformation passes copies most of the nodes and modifying only certain aspects. Therefore I need to process the same nodes in every pass, but with different xsl:template! But how do I do that? How to tell that after the first pass I want to apply templates from other XSLT stylesheet?

Very simplified example what I'm currently doing (2 XSLT passes):

Source:

<h>something here</h>

After XSLT pass 1:

<h someattribute="1">something here</h>

After XSLT pass 2:

<h someattribute="1" somemoreattribute="2">something here, and even more</h>

My current approach is to call the XSLT processor twice and saving the results temporary on disk:

xsltproc stylesheet1.xsl input.xml >temp.xml xsltproc stylesheet2.xsl temp.xml >finalresult.xml

-------------Problems Reply------------

One possible solution would be to change each of the stylesheets to use a distinct mode. Then you could import them all to your master stylesheet and do multiple passes by applying templates using each mode in turn:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
version="1.0">

<xsl:import href="stylesheet1.xsl"/> <!-- assuming mode="stylesheet1" -->
<xsl:import href="stylesheet2.xsl"/> <!-- assuming mode="stylesheet2" -->
<xsl:import href="stylesheet3.xsl"/> <!-- assuming mode="stylesheet3" -->

<xsl:template match="/">
<xsl:variable name="temp1">
<xsl:apply-templates select="." mode="stylesheet1"/>
</xsl:variable>
<xsl:variable name="temp2">
<xsl:apply-templates mode="stylesheet2" select="exsl:node-set($temp1)"/>
</xsl:variable>
<xsl:apply-templates mode="stylesheet3" select="exsl:node-set($temp2)"/>
</xsl:template>

</xsl:stylesheet>

The downside is that you need to modify the original stylesheets, adding appropriate mode attributes to each xsl:templateand xsl:apply-templates. You can still make the stylesheets also work independently by adding an extra template like this in each of them:

<xsl:template match="/">
<xsl:apply-templates select="." mode="stylesheet1"/>
</xsl:template>

Why not use

<xsl:param name="iteration"/>

And pass the iteration number to the stylesheet? You can then use it like this

<xsl:if test="$iteration = 1">
...
</xsl:if>

...or in other contexts

You can set the parameter with

javax.xml.transform.Transformer.setParameter("iteration", 1);

Or with ant:

<xslt ...>
<param name="iteration" expression="1"/>
</xslt>

Category:xslt Views:0 Time:2011-07-21
Tags: xslt exslt

Related post

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.161 (s). 11 q(s)