Subject: Re: [xsl] Slow XSLT From: Cleyton Jordan <cleytonjordan@xxxxxxxxxxx> Date: Fri, 29 Feb 2008 16:13:32 +0000 (GMT) |
Hi David, Thanks for your reply. This is what you said: " Without knowing your input or problem it's hard to give specific advice, except the advice that // should normally be avoided, either by using explict paths or by the use of keys. " My input is the XML I have shown in my previous post. Please see below. Please note that the reason I am using //ColGrp is because I do not know how many ColGrp elements I will have. It could be two, three or more. So I need to know how many ancestor ColGrp elements I have based on the $depth value which normally starts from 1 //ColGrp[count(ancestor::ColGrp)=$depth //ColGrp[count(ancestor::ColGrp)= 1 <Columns> <ColGrp heading="Quarter"> <ColGrp heading="2003"> <ColGrp heading="Name"> <Col heading="Quarter 1" /> <Col heading="Quarter 2" /> </ColGrp> </ColGrp> </ColGrp> </Columns> Please could you provide an example of how I could use a key to speed up the process? This is a sample of the desired output using only the 2003 ColGrp column not the 2004 2003 Quarter 1 Quarter 2 Quarter 3 Total Pages Cost Total Pages Cost Total Pages Cost Also, you said: "for the inner loop you are searching the document for Col elements then each time searching the document again for measures elements (this search returns the same nodes each time, so it may be worth saving this in variable before the Col loop " You are right. So, are you suggesting that I should use something like this: <xsl:variable name="msrsNodeSet" select="Reports/Report/Measures/Measure"/> The reason why I need to apply template to every Measure elements is because each Measure element is the headin of the inner most <td>s. (ColGrp) Quarter 1 (Measure) Total Pages Cost I would appreciate if you could show me some examples of how I could improve this XSLT. Cheers C === ------------------------------ Date: Fri, 29 Feb 2008 00:02:27 GMT To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx From: David Carlisle <davidc@xxxxxxxxx> Subject: Re: [xsl] Slow XSLT Message-Id: <200802290002.m1T02RPh001273@xxxxxxxxxxxxxxxxxxx> It's not surprising that it is slow. // is an expensive operation it means search every node in the document, and you are doing it in a nested fashion, so unless your system rewrites your stylesheet if your time at least the square (or cube ?) of the number of nodes in your document which can get slow... Without knowing your input or problem it's hard to give specific advice, except the advice that // should normally be avoided, either by using explict paths or by the use of keys. for the outer //ColGrp, if you know where they are then using /a/b/c/ColGrp is likely to be quicke, as it saves searching the entire document for them. for the inner loop you are searching the document for Col elements then each time searching the document again for measures elements (this search returns the same nodes each time, so it may be worth saving this in variable before the Col loop, although your xslt system may be able to do that rewrite automatically, do you really need to apply templates to every Measures eleemnt in the document, for every Col in the document? this seems unlikely but as I don't know what the transform is I can't suggest any changes. David ==== Date: Thu, 28 Feb 2008 22:59:48 +0000 (GMT) To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx From: Cleyton Jordan <cleytonjordan@xxxxxxxxxxx> Subject: Slow XSLT Message-ID: <323507.70372.qm@xxxxxxxxxxxxxxxxxxxxxxxxxxx> Hi, I am using XSLT 1.0 and IE6 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. 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/ ___________________________________________________________ Yahoo! Photos NEW, now offering a quality print service from just 8p a photo http://uk.photos.yahoo.com
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Slow XSLT, David Carlisle | Thread | Re: [xsl] Slow XSLT, David Carlisle |
[xsl] Use of data() function (was: , Mukul Gandhi | Date | Re: [xsl] Use of data() function (w, Andrew Welch |
Month |