Subject: RE: Slow XSLT
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sat, 1 Mar 2008 23:34:11 -0000
|
> I have written the XSLT below and it works fine.
> However, when the XML has lots of RowGrp elements then it
> becomes quite slow to transform.
I see no RowGrp elements, I assume you mean ColGrp...
Its easy to see why your code is slow. But I'm afraid I can't suggest any
way to speed it up, because I simply can't work out what it is trying to do.
You haven't given any clues, and reverse engineering the requirements from
some rather strangely-written code is not easy.
Michael Kay
http://www.saxonica.com/
>
> The difficulty that I am having is to find a way to speed it
> up. I think there could be two problems with my XSLT:
>
> 1 - Recursion in the ColGrp Template mode="header"
>
> <xsl:for-each
> select="//ColGrp[count(ancestor::ColGrp)=$depth]">
>
> 2 - Also, when I am in the Col Template I have to go back to
> the measures element for each Col
>
> <xsl:for-each select="//Col">
> <xsl:apply-templates select="//Measures">
> <xsl:with-param name="pos" select="position()" />
> </xsl:apply-templates>
> </xsl:for-each>
>
> I would appreciate if someone could sched some light.
> I have read Jeni's XSLT pages (key and grouping) but have not
> found any posts or example similar to mine.
>
> Cheers
>
> C
> ===========================
> XML
> <Reports>
> <Report xmlns="">
> <Measures>
> <Measure idx="1" heading="Total Pages" />
> <Measure idx="2" heading="Cost" />
> </Measures>
> <Columns>
> <ColGrp heading="Quarter">
> <ColGrp heading="2003">
> <Col heading="Quarter 1" />
> <Col heading="Quarter 2" />
> <Col heading="Quarter 3" />
> <Col heading="Quarter 4" />
> </ColGrp>
> <ColGrp heading="2004">
> <Col heading="Quarter 1" />
> <Col heading="Quarter 2" />
> <Col heading="Quarter 3" />
> <Col heading="Quarter 4" />
> </ColGrp>
> </ColGrp>
> <!--===TOTALS====-->
> <ColGrp>
> <ColGrp>
> <Col heading="Total" />
> </ColGrp>
> </ColGrp>
> </Columns>
> </Report>
> </Reports>
>
> ==============================
>
> XSLT
>
> <xsl:param name="axisHeads" select="'false'" />
>
> <xsl:variable name="msrs">
> <xsl:choose>
> <xsl:when test="//Measure">
> <xsl:value-of select="count(//Measure)"/>
> </xsl:when>
> <xsl:otherwise>
> <xsl:value-of select="1"/>
> </xsl:otherwise>
> </xsl:choose>
> </xsl:variable>
>
> <xsl:template match="Reports">
> <xsl:apply-templates
> select="Report"></xsl:apply-templates>
> </xsl:template>
>
> <xsl:template match="Report" >
> <!-- Top -->
> <div id="g1" style="position: absolute; top:
> 0px; left: 0px; width: 400px; height: 12px">
> <table class="grdTop" border="0"
> cellspacing="1" cellpadding="0">
> <tbody>
> <xsl:apply-templates select="Columns" />
> </tbody>
> </table>
> </div>
> </xsl:template>
>
> <xsl:template match="Columns">
> <xsl:apply-templates select="ColGrp[1]"
> mode="Header">
> <!-- 0 for top level heading, 1 to cut it out
> -->
> <xsl:with-param name="depth">
> <xsl:choose>
> <xsl:when test="$axisHeads='true'">
> <xsl:value-of select="0"/>
> </xsl:when>
> <xsl:otherwise>
> <xsl:value-of select="1"/>
> </xsl:otherwise>
> </xsl:choose>
> </xsl:with-param>
> </xsl:apply-templates>
> </xsl:template>
>
> <xsl:template match="ColGrp" mode="Header">
> <xsl:param name="depth" />
> <tr>
> <!-- the very first row needs a padding cell -->
> <xsl:for-each
> select="//ColGrp[count(ancestor::ColGrp)=$depth]">
> <td colspan="{count(.//Col)*$msrs}"
> align="center" style="overflow:none">
> <nobr>
> <div>
> <xsl:value-of select="@heading"/>
> </div>
> </nobr>
> </td>
> </xsl:for-each>
> </tr>
> <xsl:choose>
> <xsl:when test="ColGrp">
> <xsl:apply-templates select="ColGrp[1]"
> mode="Header">
> <xsl:with-param name="depth"
> select="$depth+1" />
> </xsl:apply-templates>
> </xsl:when>
> <xsl:otherwise>
> <xsl:apply-templates select="Col[1]"
> mode="colHead" />
> </xsl:otherwise>
> </xsl:choose>
> </xsl:template>
>
> <xsl:template match="Col" mode="colHead">
> <tr>
> <xsl:for-each select="ancestor::Columns//Col">
> <td colspan="{$msrs}" valign="top"
> align="center" style="overflow:none">
> <nobr>
> <!-- 2003/2004 -->
> <div>
> <xsl:value-of select="@heading"/>
> </div>
> </nobr>
> </td>
> </xsl:for-each>
> </tr>
> <tr valign="bottom">
> <xsl:for-each select="//Col">
> <xsl:apply-templates select="//Measures">
> <xsl:with-param name="pos"
> select="position()" />
> </xsl:apply-templates>
> </xsl:for-each>
> </tr>
> </xsl:template>
>
> <xsl:template match="//Measures">
> <xsl:param name="pos" />
> <xsl:for-each select="Measure">
> <xsl:variable name="mPos">
> <xsl:value-of select="position()" />
> </xsl:variable>
> <td align="center">
> <nobr>
> <div class="action" style="width:90px;
> overflow:none" onclick="sortFullGrid({$mPos}, {$pos}, '{@class}')">
> <xsl:value-of select="@heading"/>
> </div>
> </nobr>
> </td>
> </xsl:for-each>
> </xsl:template>
>
>
>
> ___________________________________________________________
> Rise to the challenge for Sport Relief with Yahoo! For Good
>
> http://uk.promotions.yahoo.com/forgood/
|