Subject: Re: [xsl] How to output open/close tags independently? From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Thu, 26 Dec 2002 23:56:17 -0800 (PST) |
"Mitch Amiano" <mitch.amiano@xxxxxxxxxxxxxxxxxxxx> wrote in message news:3E0B8F7F.6050609@xxxxxxxxxxxxxxxxxxxxxxx > I don't see what the connection is between trying to coerce XSLT into accepting non-well-formed markup, and grouping. > As others have pointed out, the FAQ gives a good example of how to group by a fixed number of elements. For grins, I took your sample and modified it slightly: > <?xml version="1.0"?> > <batchup> > <x>0</x> > <x>1</x> > <x>2</x> > <x>3</x> > <x>4</x> > <x>5</x> > <x>6</x> > <x>7</x> > <x>8</x> > <x>9</x> > <x>0</x> > <x>1</x> > <x>2</x> > > ... and so on, for 1000 <x> elements. > > Then I wrote a small stylesheet based on the FAQ method: > > <xsl:variable name="groupsize" select="3"/> > <xsl:template match="/"> > <xsl:for-each select="batchup/x[position() mod $groupsize = 1]"> > <xsl:text>
</xsl:text> > <w> > <xsl:copy-of select=".|following-sibling::x[position() < $groupsize]"/> > </w> > </xsl:for-each> > </xsl:template> > > and another based on a recursive call-template: > > <xsl:variable name="groupsize" select="3"/> > <xsl:template match="/"> > <xsl:call-template name="batchup"> > <xsl:with-param name="nodes" select="/batchup/x"/> > </xsl:call-template> > </xsl:template> > <xsl:template name="batchup"> > <xsl:param name="nodes"/> > <xsl:if test="$nodes"> > <xsl:text>
</xsl:text> > <w> > <xsl:copy-of select="$nodes[position() <= $groupsize]"/> > </w> > <xsl:call-template name="batchup"> > <xsl:with-param name="nodes" select="$nodes[position() > $groupsize]"/> > </xsl:call-template> > </xsl:if> > </xsl:template> > > Not surprisingly, the second transform took about 5 times longer to run (83.34 seconds on w2k/saxon6.5.1/750mhz) than the first one (17.46 seconds) (and Windows complained about my virtual memory usage). Not to mention that the first transform is a smaller amount of code. > > - Mitch Hi Mitch, My results are *very different*. With your set of 1000 elements On Saxon 6.5.2 I have: --------------------- non-resursive: 0.251 sec recursive: 0.280 sec It was more than a year ago when Mike Kay explained that Saxon optimises tail recursion implementing it with iteration. This explains the result. On MSXML4 (, which does not optimise tail-recursion) the results are: ---------- non-recursive: 0.005 sec. recursive: 0.046 sec. so the recursive variant ran 9 times slower. However, there's a DVC variant (Divide and Conquer, see for example http://www.topxml.com/code/default.asp?p=3&id=v20020107050418&ms=60&l=xsl&sw=lang), which allows recursion to run much faster. With it the results were: Saxon 6.5.2: ----------- non-resursive: 0.251 sec recursive: 0.280 sec DVC: 0.280 sec MSXML4: ------- non-recursive: 0.005 sec. recursive: 0.046 sec. DVC: 0.014 sec. My computer is a 1.7 GHz W2K Pentium with 256MB of memory. This is the reason for the faster times. However, the difference in speed cannot explain the very different ratio of recursive / non-recursive reported by you for Saxon. Here's the code I used (copied your code and added the DVC one): ---------------------- <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="groupsize" select="3"/> <!-- <xsl:template match="/"> <xsl:call-template name="batchup"> <xsl:with-param name="nodes" select="/batchup/x"/> </xsl:call-template> </xsl:template> <xsl:template name="batchup"> <xsl:param name="nodes"/> <xsl:if test="$nodes"> <xsl:text>
</xsl:text> <w> <xsl:copy-of select="$nodes[position() <= $groupsize]"/> </w> <xsl:call-template name="batchup"> <xsl:with-param name="nodes" select="$nodes[position() > $groupsize]"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template match="/"> <xsl:for-each select="batchup/x[position() mod $groupsize = 1]"> <xsl:text>
</xsl:text> <w> <xsl:copy-of select=".|following-sibling::x[position() < $groupsize]"/> </w> </xsl:for-each> </xsl:template> --> <xsl:template match="/"> <xsl:call-template name="batchup"> <xsl:with-param name="nodes" select="/batchup/x"/> </xsl:call-template> </xsl:template> <xsl:template name="batchup"> <xsl:param name="nodes"/> <xsl:if test="$nodes"> <xsl:choose> <xsl:when test="not($nodes[position() = $groupsize + 1])"> <xsl:text>
</xsl:text> <w> <xsl:copy-of select="$nodes[position() <=$groupsize]"/> </w> </xsl:when> <xsl:otherwise> <xsl:variable name="vHalf" select="floor(ceiling(count($nodes) div $groupsize) div 2) * $groupsize"/> <xsl:call-template name="batchup"> <xsl:with-param name="nodes" select="$nodes[position() <= $vHalf]"/> </xsl:call-template> <xsl:call-template name="batchup"> <xsl:with-param name="nodes" select="$nodes[position() > $vHalf]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:template> </xsl:stylesheet> ===== Cheers, Dimitre Novatchev. http://fxsl.sourceforge.net/ -- the home of FXSL __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] How to output open/close , Passin, Tom | Thread | Re: [xsl] How to output open/close , Mitch Amiano |
Re: [xsl] amp and &, Mike Brown | Date | RE: [xsl] Closing and opeing tag in, Mike Ferrando |
Month |