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

Re: Formatting elements. (flat -> group. For Jeni ).

Subject: Re: Formatting elements. (flat -> group. For Jeni ).
From: Paul Tchistopolskii <paul@xxxxxxx>
Date: Fri, 13 Oct 2000 22:32:37 -0700
x when count
----- Original Message -----
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>

> I'm be very grateful if
> you could post the (generated) XSLT from the completed solution (with the
> new first-breaking-pos template) so that I can see more clearly how to
> apply it in future cases where I'm faced with this problem.

Sorry - it took some time for me to rewrite the XSLScript parser itself
( I wanted to use a new XSLScript syntax for this example.)

As promised - the stylesheet structure remains the same - just
a bunch of new functions added ( XSLT is now huge ;-).

I'm not happy with the results ( even it took 15 minutes to write
this beast and it could be shorter - some functions are for
readability only, but... )

In the next version of XSLScript I'll try approaching some more non-XSLT
macro-constructions  ( similar to 'else' , but related to recursion ). Anybody
wants to help in brainstorming?  I know about the Oliver's loop solution, but
I'm thinking about something more flexible. Maybe saxon:evaluate is our
friend? Ah, nevermind...

Input:

<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='bullet1'><text/></item>
 <item name='bullet2'><text/></item>
 <item name='bullet3'>some text for item 3</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>
 <item name='para'><text>paragraph text</text></item>
 <item name='menu1'><text>some text for menu 1</text></item>
 <item name='menu2'><text>some text for menu 2</text></item>
 <item name='menu3'><text/></item>
 <item name='menu1'><text>some text for menu 1</text></item>
 <item name='menu2'><text>some text for menu 2</text></item>
 <item name='menu3'><text/></item>
</document>

Output:

C:\WORK\XslScript\XslScript07>xsls flat.xml flat.xsls
<?xml version="1.0" encoding="utf-8"?>
<document>
   <title>Title field</title>
   <bulletlist>
      <bullet>some text for item 1</bullet>
      <bullet>some text for item 2</bullet>
      <bullet/>
   </bulletlist>
   <bulletlist>
      <bullet/>
      <bullet/>
      <bullet>some text for item 3</bullet>
   </bulletlist>
   <para>paragraph text</para>
   <bulletlist>
      <bullet>some text for item 1</bullet>
      <bullet>some text for item 2</bullet>
      <bullet/>
      <bullet/>
   </bulletlist>
   <para>paragraph text</para>
   <menulist>
      <menu>some text for menu 1</menu>
      <menu>some text for menu 2</menu>
      <menu/>
   </menulist>
   <menulist>
      <menu>some text for menu 1</menu>
      <menu>some text for menu 2</menu>
      <menu/>
   </menulist>
</document>

XSLScript code:

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:var listname = { !get-listname( itm="$type" ) }
         X:var elmname  = { !get-elmname( itm="$type" ) }

        X:if "string($listname)"  {

              X:var
on={ 
                   !get-brkon( cur="$type", list="$list[ position() &gt; 1 ]", count={1} ) 
              }
                
              X:element "{$listname}" {
                 X:for-each "$list[ not(position() &gt; $brkon) ]" {
                       X:element "{$elmname}" { !{.} }
                 }
              }

              !render-flat( list="$list[ position() &gt; $brkon ]" )

     } else {

              X:element "{$elmname}" { !{ $list[1] } }
              !render-flat( list="$list[ position() &gt; 1]" ) 
     }
  }
}

X:template get-listname( itm ) {
     X:choose {
          X:when "starts-with( $itm, 'bull
et' )" {bulletlist}
          X:when "starts-with( $itm, 'menu' )" {menulist}
          X:otherwise {}
     }
}

X:template get-elmname( itm ) {
     X:choose {
          X:when "starts-with( $itm, 'bullet' )" {bullet}
          X:when "starts-with( $itm, 'menu' )" {menu}
          X:otherwise { !{$itm} }
     }
}

X:template get-brkon( cur, list, count ) {

  X:if "$list" {

  X:var curel = { !get-elmname( itm="$cur" ) }
  X:var curnum = { !get-number( itm="$cur" ) }

  X:var head = "string($list[1]/@name)"

  X:var hel = { !get-elmname( itm="$head" ) }
  X:var hnum = { !get-number( itm="$head" ) }

          X:if " $curel = $hel and number($curnum) &lt; number($hnum)" {
                   !get-brkon( cur= "$head" , list= "$list[ position() &gt; 1 ]" , count=
"$count + 1" )
          } else {
                  !{$count}
          }
 } else {
         !{$count}
 }
}

X:template get-number( itm )

     !{translate($itm, 'abcdefghijklmnopqrstuvwxyz', ' ')}
}

}

XSLT ( generated ):

<?xml version="1.0" encoding="utf-8"?>
<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:variable name="listname">
            <xsl:call-template name="get-listname">
               <xsl:with-param select="$type" name="itm"/>
            </xsl:call-template>
         </xsl:variable>
         <xsl:variable name="elmname">
            <xsl:call-template name="get-elmname">
               <xsl:with-param select="$type" name="itm"/>
            </xsl:call-template>
         </xsl:variable>
         <xsl:choose>
            <xsl:when test="string($listname)">
               <xsl:variable name="brkon">
                  <xsl:call-template name="get-brkon">
                     <xsl:with-param select="$type" name="cur"/>
                     <xsl:with-param select="$list[ position() &gt; 1 ]" name="list"/>
                     <xsl:with-param name="count">1</xsl:with-param>
                  </xsl:call-template>
               </xsl:variable>
               <xsl:element name="{$listname}">
                  <xsl:for-each select="$list[ not(position() &gt; $brkon) ]">
                     <xsl:element name="{$elmname}">
                        <xsl:value-of select="."/>
                     </xsl:element>
                  </xsl:for-each>
               </xsl:element>
               <xsl:call-template name="render-flat">
                  <xsl:with-param select="$list[ position() &gt; $brkon ]" name="list"/>
               </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
               <xsl:element name="{$elmname}">
                  <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="get-listname">
      <xsl:param name="itm"/>
      <xsl:choose>
         <xsl:when test="starts-with( $itm, 'bullet' )">bulletlist</xsl:when>
         <xsl:when test="starts-with( $itm, 'menu' )">menulist</xsl:when>
         <xsl:otherwise/>
      </xsl:choose>
   </xsl:template>

   <xsl:template name="get-elmname">
      <xsl:param name="itm"/>
      <xsl:choose>
         <xsl:when test="starts-with( $itm, 'bullet' )">bullet</xsl:when>
         <xsl:when test="starts-with( $itm, 'menu' )">menu</xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$itm"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <xsl:template name="get-brkon">
      <xsl:param name="cur"/>
      <xsl:param name="list"/>
      <xsl:param name="count"/>
      <xsl:choose>
         <xsl:when test="$list">
            <xsl:variable name="curel">
               <xsl:call-template name="get-elmname">
                  <xsl:with-param select="$cur" name="itm"/>
               </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="curnum">
               <xsl:call-template name="get-number">
                  <xsl:with-param select="$cur" name="itm"/>
               </xsl:call-template>
            </xsl:variable>
            <xsl:variable select="string($list[1]/@name)" name="head"/>
            <xsl:variable name="hel">
               <xsl:call-template name="get-elmname">
                  <xsl:with-param select="$head" name="itm"/>
               </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="hnum">
               <xsl:call-template name="get-number">
                  <xsl:with-param select="$head" name="itm"/>
               </xsl:call-template>
            </xsl:variable>
            <xsl:choose>
               <xsl:when test=" $curel = $hel and number($curnum) &lt; number($hnum)">
                  <xsl:call-template name="get-brkon">
                     <xsl:with-param select="$head" name="cur"/>
                     <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:template name="get-number">
      <xsl:param name="itm"/>
      <xsl:value-of select="translate($itm, 'abcdefghijklmnopqrstuvwxyz', ' ')"/>
   </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.