Subject: Re: Formatting elements From: Paul Tchistopolskii <paul@xxxxxxx> Date: Tue, 03 Oct 2000 22:49:27 -0700 |
----- Original Message ----- From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> > <document> > <item name='title'><text>Title field</text></item> > <item name='bullet1'><text>some text for item 1</text></item> > <item name='bullet2'><text>some text for item 2</text></item> > <item name='bullet3'><text/></item> > <item name='bullet4'><text/></item> > <item name='bullet5'><text/></item> > <item name='bullet6'><text/></item> > <item name='para'><text>paragraph text</text></item> > <item name='bullet1'><text>some text for item 1</text></item> > <item name='bullet2'><text>some text for item 2</text></item> > <item name='bullet3'><text/></item> > <item name='bullet4'><text/></item> > </document> > > which you want to be: > > <document> > <title>Title field</title> > <bulletlist> > <bullet>some text for item 1</bullet> > <bullet>some text for item 2</bullet> > <bullet></bullet> > <bullet></bullet> > <bullet></bullet> > <bullet></bullet> > </bulletlist> > <para>paragraph text</para> > <bulletlist> > <bullet>some text for item 1</bullet> > <bullet>some text for item 2</bullet> > <bullet></bullet> > <bullet></bullet> > </bulletlist> > </document> > Below please find another ( pure functional ) solution. I'll first give XSLScript notation and then will be the XSL code ( generated, as usual ). I think this should illustrate the real value of terseness. I think the biggest problem of this transformation is XSL verbosity, because the transformation itself is not complex at all. It is Composed of 2 simple steps : If it is 'bullet' - see when 'bulletlist' ends : split on that point and call yourself again. I think this 'split / call yourself ' is the the core pattern which any XSL developer should learn ( the same happens with counters e t.c. ) There is a small 'drawback' similar to 'drawback' of my solution to Sebastian's test6, but I'm better not to start this all again. Whatever. X:transform { X:output indent="yes"; X:template = "document" { <document> <% !render-flat( list="item") %> </document> } X:template render-flat( list ) { <% X:if "$list" { <% X:var type="string($list[1]/@name)" %> <% X:if "starts-with( $type, 'bullet' )" { <% X:var fnbul={ <% !first-non-bul( list="$list", count={1} ) %> } %> <bulletlist> <% X:for-each "$list[ position() < $fnbul ]" { <bullet> <% {.} %> </bullet> } %> </bulletlist> <% !render-flat( list="$list[ not ( position() < $fnbul )]" ) %> } else <% X:element "{$type}" { <% { $list[1] } %> } %> <% !render-flat( list="$list[ position() > 1]" ) %> } %> } %> } X:template first-non-bul( list, count ) { <% X:if "$list" { <% X:var type="string($list[1]/@name)" %> <% X:if "starts-with( $type, 'bullet' )" { <% !first-non-bul( list="$list[ position() > 1 ]", count="$count + 1" ) %> } else { <% {$count} %> } %> } else { <% {$count} %> } %> } } Here is the XSL. ------------------------ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <xsl:template match="document"> <document> <xsl:call-template name="render-flat"> <xsl:with-param select="item" name="list"/> </xsl:call-template> </document> </xsl:template> <xsl:template name="render-flat"> <xsl:param name="list"/> <xsl:if test="$list"> <xsl:variable select="string($list[1]/@name)" name="type"/> <xsl:choose> <xsl:when test="starts-with( $type, 'bullet' )"> <xsl:variable name="fnbul"> <xsl:call-template name="first-non-bul"> <xsl:with-param select="$list" name="list"/> <xsl:with-param name="count">1</xsl:with-param> </xsl:call-template> </xsl:variable> <bulletlist> <xsl:for-each select="$list[ position() < $fnbul ]"> <bullet> <xsl:value-of select="."/> </bullet> </xsl:for-each> </bulletlist> <xsl:call-template name="render-flat"> <xsl:with-param select="$list[ not ( position() < $fnbul )]" name="list"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:element name="{$type}"> <xsl:value-of select=" $list[1]"/> </xsl:element> <xsl:call-template name="render-flat"> <xsl:with-param select="$list[ position() > 1]" name="list"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:template> <xsl:template name="first-non-bul"> <xsl:param name="list"/> <xsl:param name="count"/> <xsl:choose> <xsl:when test="$list"> <xsl:variable select="string($list[1]/@name)" name="type"/> <xsl:choose> <xsl:when test="starts-with( $type, 'bullet' )"> <xsl:call-template name="first-non-bul"> <xsl:with-param select="$list[ position() > 1 ]" name="list"/> <xsl:with-param select="$count + 1" name="count"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$count"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$count"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: Formatting elements, Jeni Tennison | Thread | Re: Formatting elements, Jeni Tennison |
HTML parameters and Ampersands, David_Benua | Date | RE: ANN: XSLBench - XSLT Processor , Lee Goddard |
Month |