As David has pointed out the // operator is very costly. So I have
replaced them by explicit xpath expressions and would be interested
about the performance now. However I could not resist to replace
count(.//Col)*$msrs
by
count(Col)*$msrs
Most of the rest I have l left unchanged. I also noticed the
depreciated <nobr>, which should be replaced by css white-space:
nowrap.
Manfred
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="axisHeads" select="'false'" />
<!--
java -jar D:\Programme\Saxon6\saxon.jar slow.xml slow.xsl
-->
<xsl:output indent="yes"/>
<xsl:variable name="msrs">
<xsl:choose>
<xsl:when test="/Reports/Report/Measures/Measure">
<xsl:value-of select="count(/Reports/Report/Measures/Measure)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:template match="Reports">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</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="/Reports/Report/Columns/ColGrp/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/ColGrp/ColGrp/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="/Reports/Report/Columns/ColGrp/ColGrp/Col">
<xsl:apply-templates select="/Reports/Report/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>
</xsl:stylesheet>
On 29/02/2008, Cleyton Jordan <cleytonjordan@xxxxxxxxxxx> wrote:
> Hi David,
>
>
>
> >without following in detail what processing you are
> >doing it's hard to
> > say
>
> >sorry got to dash, perhaps someone else can say more!
>
> >David
>
>
>
> I need to build a nested heading Rows/Columns (<TR>
> and <TD>). The output should look like this for the
> 2003 heading:
>
>
> 2003
> Quarter 1 Quarter 2 Quarter 3
> Quarter 4
> Total Pages Cost Total Pages Cost Total Pages Cost
>
> Total Pages Cost
>
>
> <ColGrp heading="Quarter">
> <ColGrp heading="2003">
> <Col heading="Quarter 1" />
> <Col heading="Quarter 2" />
> <Col heading="Quarter 3" />
> <Col heading="Quarter 4" />
> </ColGrp>
> </ColGrp>
>
>
> I use the xpath below to get me to the inner most
> ColGrp (parent of Col elements).
>
> Normally $depth = 1
>
> //ColGrp[count(ancestor::ColGrp)=$depth]
>
>
> //ColGrp[count(ancestor::ColGrp)=1]
>
> So, I go to the ancestor:ColGrp whose depth = 1
>
> This will produce the first <TD>s
>
> 2003 2004
>
> Then all the Col elements will produce the second row
> with all the <TD>s
>
> Quarter 1 Quarter 2 Quarter 3 Quarter 4
>
> And lastly, for each Col element I have to go back to
> the Measure elements to produce the final Row which
> will be the same for all the Col elements
>
>
> Total Pages Cost Total Pages Cost Total Pages Cost
>
> Total Pages Cost
>
> Therefore, this is the output I get with my XSLT but
> it is too slow for big xml docs.
>
> 2003
> Quarter 1 Quarter 2 Quarter 3 Quarter 4
>
> Total Pages Cost Total Pages Cost Total Pages Cost
>
>
> Cheers
>
> C
>
>
> ___________________________________________________________
>
> Rise to the challenge for Sport Relief with Yahoo! For Good
>
> http://uk.promotions.yahoo.com/forgood/
|