Subject: Re: [xsl] Slow XSLT From: Cleyton Jordan <cleytonjordan@xxxxxxxxxxx> Date: Fri, 14 Mar 2008 21:42:48 +0000 (GMT) |
Hi Manfred, Thanks again for your assistance. It is really appreciated. I will try your sample code and let you know what happens. Also, as I mentined before, I am trying to build a GRID and will send to you a copy of my latest XSLT so that you can see what I have achieved so far. Slowly I am getting there :-) THE GRID Basically, I use four <DIV> and <TABLE> tags. I have the Top Left DIV, Top Right DIV, Bottom Left DIV and Bottom Rght DIV. Because I use Javascript to align my GRID, I have to apply templates in a certain order i.e: 1- build the bottom right section first (grdBody) 2- next build the top right section (column headings) 3- Build the bottom left section (row headings) 4- Finaly build the top left section which is just an empty div with the right hight and width to align with the rest of the grid. Please note that I still have to change my XSLT code to use the sample code you showed me (call template and tail recursion). I am still using my old key way I mentioned to you. I am struggling a bit with some of the suggestions I have received specially the sample code provided by David Carlisle. He showed me how to use a technique that Michael calls vanilla push-processing. However, since I have to sort the xml based on some parameters passed to the stylesheet, I am not sure where to add the <xsl:sort> command with <apply-templates>. I have to sort 3 sections of the xml. This is how I used to do: <xsl:sort select ="Cell[number($sortCell)]/descendant::Msr[number($sortCol)]/@val" data-type="{$dataType}" order ="{$sortOrder}" /> I have to sort all the rows except for the last one - the Total row of course :-). That is the reason for the when test: OLD REPORT TEMPLATE WITH SORTING <xsl:template match="Report" > <!-- grdBdy --> <div id="{$id}grdBdy"> <table id="tblTop" cellpadding="0"> <tbody> <xsl:choose> <xsl:when test="number($sortCol) != 0"> <xsl:apply-templates select="/Reports/Report/Rows//Row" mode="data"> <xsl:sort select ="Cell[number($sortCell)]/descendant::Msr[number($sortCol)]/@val" data-type="{$dataType}" order ="{$sortOrder}" /> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="/Reports/Report/Rows//Row" mode="data" /> </xsl:otherwise> </xsl:choose> </tbody> </table> </div> </xsl:template> I also have to add a sort command to sort the Row Headings: OLD REPORT TEMPLATE WITH ROW HEADING SORTING <xsl:template match="Report" > <!-- grdLeft --> <div id="{$id}grdLft" style="position: absolute; top: 12px; left: 0px; width: 150px; height: {$height}px"> <table width="100%" class="grdMain" border="0" cellspacing="1" cellpadding="0"> <tbody> <xsl:choose> <xsl:when test="number($sortCol) != 0"> <xsl:apply-templates select="Rows//Row" mode="heading"> <xsl:sort select ="Cell[number($sortCell)]/descendant::Msr[number($sortCol)]/@val" data-type="{$dataType}" order ="{$sortOrder}" /> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="Rows//Row" mode="heading" /> </xsl:otherwise> </xsl:choose> </tbody> </table> </div> </xsl:template> Please note that I used to be able to control all these sections using the MODE ATTRIBUTE <xsl:apply-templates select="Rows//Row" mode="heading"> However, with apply-templates I might not have this control. What do you think? The last place I have to sort is in the Cell template. Please note that I have removed this sort command from my latest XSLT because I am not sure how to do that now. <xsl:template match="Cell"> <xsl:choose> <xsl:when test="Msr"> <xsl:for-each select="Msr"> <xsl:sort select="@idx" order="ascending" data-type="number"/> <xsl:choose> ..... .... </xsl:template> I would appreciate your suggestion about the sorting issues I mentioned above and also any other improvement you may find possible. Just one last note, I still have to figure out the best way to deal with the ROW HEADINGS. Still using old code like <xsl:if test="preceding-sibling::Row=false() or number($sortCol) != 0"> <xsl:apply-templates select="parent::RowGrp" mode="heading" />. How difficult do you think it would be to change my approach of using 4 DIVs and 4 Tables to build the grid and instead creating just one table? However, I would have to make sure I get my rowspan and colspan right for the first TD in the first <tr>. Cheers C XSLT ____ <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" version="1.0" encoding="iso-8859-1" indent="yes"/> <xsl:strip-space elements="*"/> <!--<xsl:decimal-format name="fd1" decimal-separator="." grouping-separator="," NaN=" \"/>--> <xsl:param name="axisHeads" select="'false'"/> <xsl:param name="sortCol" select="'0'"/> <xsl:param name="sortCell" select="'0'"/> <xsl:param name="dataType" select="'number'"/> <xsl:param name="sortOrder" select="'descending'"/> <xsl:param name="ltCurFormat" select="'$##,###.00'"/> <xsl:param name="ltNumFormat" select="'###,.00'"/> <xsl:param name="heading"/> <xsl:param name="height" select="'500'"/> <xsl:param name="width" select="'880'"/> <xsl:param name="id" select="'audit'"/> <xsl:variable name="nrmr" select="count(/Report/Measures/Measure)"/> <xsl:variable name="msrs" select="/Report/Measures/Measure"/> <xsl:variable name="colSet" select="/Report/Columns/ColGrp/descendant::Col"/> <xsl:key name="c" match="ColGrp" use="count(ancestor::ColGrp)"/> <xsl:template match="Report"> <!-- outer div to contain all four grid elements --> <div id="{$id}dvGrid" class="grdVP" style="position: relative; height: {$height}px; width: {$width}px; overflow: hidden; clip: rect(0px, {$width}px, {$height}px, 0px);"> <!-- grdBdy --> <div id="{$id}grdBdy" style="position: relative; width: {$width}px; height: {$height}px; overflow:auto" onscroll="scrollFullGrid(this)"> <table class="grdMain" id="tblTop" border="0" cellspacing="1" cellpadding="0"> <tbody> <xsl:choose> <xsl:when test="number($sortCol) != 0"> <xsl:apply-templates> <xsl:sort select ="Cell[number($sortCell)]/descendant::Msr[number($sortCol)]/@val" data-type="{$dataType}" order ="{$sortOrder}" /> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </tbody> </table> </div> <div id="{$id}grdTop" style="position: absolute; top: 0px; left: 0px; width: {$width}px; height: 12px"> <table class="grdTop" border="0" cellspacing="1" cellpadding="0"> <tbody> <xsl:apply-templates select="Columns" mode="Column"/> </tbody> </table> </div> <!-- grdLeft --> <div id="{$id}grdLft" style="position: absolute; top: 12px; left: 0px; width: 150px; height: {$height}px"> <table width="100%" class="grdMain" border="0" cellspacing="1" cellpadding="0"> <tbody> <xsl:choose> <xsl:when test="number($sortCol) != 0"> <xsl:apply-templates select="Rows//Row" mode="heading"> <xsl:sort select ="Cell[number($sortCell)]/descendant::Msr[number($sortCol)]/@val" data-type="{$dataType}" order ="{$sortOrder}" /> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="Rows//Row" mode="heading" /> </xsl:otherwise> </xsl:choose> </tbody> </table> </div> <!-- grdTL the filler space - formerly the td with colspan and rowspan --> <div id="{$id}grdTL" class="grdTL" style="position: absolute; width:150px;height:12px"> <div></div> </div> </div> </xsl:template> <!--== ROW DATA ==--> <xsl:template match="Row"> <tr> <xsl:apply-templates/> </tr> </xsl:template> <xsl:template match="Msr"> <xsl:variable name="numberVal" select="@val"/> <xsl:choose> <!--<xsl:when test="string(number(@val)) ='NaN'">--> <xsl:when test="not(number($numberVal))"> <td align="left" style="overflow:none"> <nobr> <div style="width:80px;overflow:none"> <xsl:value-of select="$numberVal"/> </div> </nobr> </td> </xsl:when> <xsl:otherwise> <td align="right" style="overflow:none"> <nobr> <div style="width:80px;overflow:none"> <!--<xsl:variable name="numberVal" select="@val"/>--> <xsl:variable name="style" select="@class"/> <xsl:if test="$numberVal != ''"> <xsl:choose> <xsl:when test="$style='num1'"> <xsl:value-of select="format-number($numberVal,'###,')"/> </xsl:when> <xsl:when test="$style='cur1'"> <xsl:value-of select="format-number($numberVal,$ltCurFormat)"/> </xsl:when> <!--<xsl:when test="$numberVal = '-1' or $numberVal = '0'"> <xsl:text xml:space="preserve">-</xsl:text> </xsl:when>--> <xsl:when test="$numberVal = '-1' or $numberVal = '0'"> <xsl:text xml:space="preserve">-</xsl:text> </xsl:when> <xsl:when test="$style='percent'"> <xsl:value-of select="format-number($numberVal * 100,'0.00')"/> <xsl:text>%</xsl:text> </xsl:when> <xsl:otherwise> <xsl:value-of select="format-number($numberVal,$ltNumFormat)"/> </xsl:otherwise> </xsl:choose> </xsl:if> <xsl:if test="$numberVal = ''"> <xsl:text xml:space="preserve">-</xsl:text> </xsl:if> </div> </nobr> </td> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="Cell[not(*)]"> <xsl:for-each select="$msrs"> <td align="right" style="overflow:none"> <nobr> <div style="width:80px"> </div> </nobr> </td> <!--<td> </td>--> </xsl:for-each> </xsl:template> <!--== ROW DATA ==--> <!--== Columns ==--> <xsl:template match="Columns" mode="Column"> <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]">--> <xsl:for-each select="key('c', $depth)"> <!--<td colspan="{count(.//Col)*$msrs}" align="center" style="overflow:none">--> <td colspan="{count(.//Col)*$nrmr}" 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="$colSet"> <td colspan="{$nrmr}" valign="top" align="center" style="overflow:none"> <nobr> <div> <xsl:value-of select="@heading"/> </div> </nobr> </td> </xsl:for-each> </tr> <tr valign="bottom"> <xsl:for-each select="$colSet"> <xsl:apply-templates select="/Report/Measures" mode ="ColumnMeasure"> <xsl:with-param name="pos" select="position()" /> </xsl:apply-templates> </xsl:for-each> </tr> </xsl:template> <xsl:template match="Measures" mode="ColumnMeasure"> <xsl:param name="pos" /> <xsl:for-each select="$msrs"> <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> <!--== Columns ==--> <!--== ROW MODE HEADING ==--> <xsl:template match="Row" mode="heading"> <tr> <xsl:if test="preceding-sibling::Row=false() or number($sortCol) != 0"> <xsl:apply-templates select="parent::RowGrp" mode="heading" /> </xsl:if> <xsl:variable name="theHeading"> <xsl:call-template name="js-escapeAmp"> <xsl:with-param name="string"> <xsl:call-template name="js-escapeApos"> <xsl:with-param name="string" select="@heading" /> </xsl:call-template> </xsl:with-param> </xsl:call-template> </xsl:variable> <td title="{$theHeading}" style="overflow:none"> <nobr> <div> <xsl:value-of select="$theHeading"/> </div> </nobr> </td> </tr> </xsl:template> <xsl:template match="RowGrp" mode="heading"> <xsl:if test="preceding-sibling::RowGrp=false() or number($sortCol) != 0"> <xsl:apply-templates select="parent::RowGrp" mode="heading" /> </xsl:if> <xsl:if test="parent::Rows=false() or $axisHeads='true'"> <td style="overflow:none; vertical-align:top" title="{@heading}" valign="top"> <xsl:if test="number($sortCol) = 0"> <xsl:attribute name="rowspan"> <xsl:value-of select="count(.//Row)"/> </xsl:attribute> </xsl:if> <nobr> <div> <xsl:value-of select="@heading"/> </div> </nobr> </td> </xsl:if> </xsl:template> <xsl:template name="js-escapeApos"> <xsl:param name="string" /> <xsl:call-template name="substitute"> <xsl:with-param name="string" select="normalize-space($string)" /> <xsl:with-param name="find" select='"&apos;"' /> <xsl:with-param name="replace" select='"'"' /> </xsl:call-template> </xsl:template> <xsl:template name="js-escapeAmp"> <xsl:param name="string" /> <xsl:call-template name="substitute"> <xsl:with-param name="string" select="normalize-space($string)" /> <xsl:with-param name="find" select='"&amp;"' /> <xsl:with-param name="replace" select='"&"' /> </xsl:call-template> </xsl:template> <xsl:template name="substitute"> <xsl:param name="string" /> <xsl:param name="find" /> <xsl:param name="replace" /> <xsl:choose> <xsl:when test="$find and $string and contains($string, $find)"> <xsl:value-of select="substring-before($string, $find)" /> <xsl:value-of select="$replace" /> <xsl:call-template name="substitute"> <xsl:with-param name="string" select="substring-after($string,$find)" /> <xsl:with-param name="find" select="$find" /> <xsl:with-param name="replace" select="$replace" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string" /> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> --- Manfred Staudinger <manfred.staudinger@xxxxxxxxx> wrote: > On 14/03/2008, Michael Kay <mike@xxxxxxxxxxxx> > wrote: > > > A lot has already been said and many suggestions > have already > > > been made in this thread to speed up the > processing of your > > > stylesheet, but since your stylesheet is rather > > > straightforward I doubt if any of the > suggestions really ___________________________________________________________ Win a BlackBerry device from O2 with Yahoo!. Enter now. http://www.yahoo.co.uk/blackberry
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Slow XSLT, Manfred Staudinger | Thread | Re: [xsl] Slow XSLT, Manfred Staudinger |
Re: [xsl] eliminating multiple repe, David Carlisle | Date | Re: [xsl] Slow XSLT, Cleyton Jordan |
Month |