[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Formatting elements

Subject: Re: Formatting elements
From: Paul Tchistopolskii <paul@xxxxxxx>
Date: Tue, 03 Oct 2000 22:49:27 -0700
with param select
----- 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() &lt; $fnbul ]" {
                                <bullet> <% {.} %> </bullet>
                           } %>
                      </bulletlist>

                      <% !render-flat( list="$list[ not ( position() &lt; $fnbul )]" ) %>
          } else

                  <% X:element "{$type}" {
                       <% { $list[1] } %>
                  } %>

                  <% !render-flat( list="$list[ position() &gt; 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() &gt; 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() &lt; $fnbul ]">
                     <bullet>
                        <xsl:value-of select="."/>
                     </bullet>
                  </xsl:for-each>
               </bulletlist>
               <xsl:call-template name="render-flat">
                  <xsl:with-param select="$list[ not ( position() &lt; $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() &gt; 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() &gt; 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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.