Subject: Re: [xsl] Slow XSLT From: Cleyton Jordan <cleytonjordan@xxxxxxxxxxx> Date: Fri, 29 Feb 2008 23:14:41 +0000 (GMT) |
Hi Manfred, Thanks for your reply. I think I can now understand what David poited out i.e. that when using // can be very costly. However, I thought that by using // followed by a predicate ( //ColGrp[count(ancestor::ColGrp)=$depth] ), I would go straight to only those inner most ColGrp elements parent of the Col elements. There is one problem with your approach though. You are assuming that there will always be only two ColGrp like this: <xsl:for-each select="/Reports/Report/Columns/ColGrp/ColGrp[count(ancestor::ColGrp)=$depth]"> <ColGrp heading="Quarter"> <ColGrp heading="2003"> <Col heading="Quarter 1" /> <Col heading="Quarter 2" /> <Col heading="Quarter 3" /> <Col heading="Quarter 4" /> </ColGrp> </ColGrp> But That is not the case. The xml can have as many nested ColGrp as necessary. For instance: <ColGrp heading="Quarter"> <ColGrp heading="2003"> <ColGrp heading="Name"> <Col heading="Quarter 1" /> <Col heading="Quarter 2" /> <Col heading="Quarter 3" /> <Col heading="Quarter 4" /> </ColGrp> </ColGrp> </ColGrp> or <ColGrp heading="Quarter"> <ColGrp heading="2003"> <ColGrp heading="Name"> <ColGrp heading="Charity Report IO"> <Col heading="Quarter 1" /> <Col heading="Quarter 2" /> <Col heading="Quarter 3" /> <Col heading="Quarter 4" /> </ColGrp> </ColGrp> </ColGrp> </ColGrp> As you can see, there can be many ColGroup levels nested inside each other. Therefore, we need an approach that is dynamic i.e. no matter how many nested ColGrp there are, it will produce the right output. >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 > > __________________________________________________________ Sent from Yahoo! Mail. A Smarter Inbox. http://uk.docs.yahoo.com/nowyoucan.html
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Slow XSLT, Manfred Staudinger | Thread | [xsl] FW: Different conditional ou, Pankaj Chaturvedi |
RE: [xsl] java-xsl - functional(?) , XSL-List Owner | Date | Re: [xsl] Use of data() function, Florent Georges |
Month |