Re: [xsl] Table formatting challenge

Subject: Re: [xsl] Table formatting challenge
From: David Carlisle <davidc@xxxxxxxxx>
Date: Mon, 16 Jul 2001 12:23:35 +0100
Oliver>David, your turn.

Actually Norm contacted me off the list over the weekend,  I'm not
totally familiar with the American idiom, but I think it translated as
a comment that my code, whilst technically correct, was not as general
as perhaps required.

So here's a second version that isn't as elegant as the first but is
more general (although as written it only copes with row spans in single
figures)

David

======================================
<book>



<informaltable>
<tgroup cols="4">
<colspec colname="c4" colnum="4"/>
<tbody>
<row>
  <entry morerows="1">A</entry>
  <entry>B</entry>
  <entry morerows="1">C</entry>
  <entry>D</entry>
</row>
<row>
  <entry namest="c4">E</entry>
</row>
</tbody>
</tgroup>
</informaltable>



<informaltable>
<tgroup cols="4">
<colspec colname="c4b" colnum="4"/>
<tbody>
<row>
  <entry>A</entry>
  <entry>B</entry>
  <entry morerows="2">C</entry>
  <entry morerows="2">D</entry>
</row>
<row>
  <entry morerows="2">E</entry>
  <entry>F</entry>
</row>
<row>
  <entry>G</entry>
</row>
<row>
  <entry>H</entry>
  <entry namest="c4b">I</entry>
</row>
</tbody>
</tgroup>
</informaltable>




<informaltable>
<tgroup cols="4">
<colspec colname="c3c" colnum="3"/>
<colspec colname="c4c" colnum="4"/>
<tbody>
<row>
  <entry>A</entry>
  <entry morerows="2">B</entry>
  <entry>C</entry>
  <entry morerows="1">D</entry>
</row>
<row>
  <entry morerows="1">E</entry>
  <entry>F</entry>
</row>
<row>
  <entry namest="c4c">G</entry>
</row>
<row>
  <entry>H</entry>
  <entry namest="c3c">I</entry>
  <entry>J</entry>
</row>
</tbody>
</tgroup>
</informaltable>



<informaltable>
<tgroup cols="4">
<colspec colname="c3d" colnum="3"/>
<colspec colname="c4d" colnum="4"/>
<tbody>
<row>
  <entry morerows="2">A</entry>
</row>
<row>
  <entry>B</entry>
  <entry namest="c4d">C</entry>
</row>
<row>
  <entry namest="c3d" morerows="1">D</entry>
</row>
<row>
  <entry namest="c4d">E</entry>
</row>
</tbody>
</tgroup>
</informaltable>


</book>
======================================

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0"
                >

<xsl:output method="html" indent="yes"/>

<xsl:template name="informaltable">
<xsl:apply-templates select="tbody"/>
</xsl:template>

<xsl:template match="tbody">
<table border="1">
<xsl:apply-templates select="row[1]">
 <xsl:with-param name="spans">
  <xsl:for-each select="descendant::*[position()&lt;=current()/../@cols]">0</xsl:for-each>
 </xsl:with-param>
</xsl:apply-templates>
</table>
</xsl:template>

<xsl:template match="row">
<xsl:param name="spans" />
<tr>
<xsl:apply-templates select="entry[1]">
 <xsl:with-param name="spans" select="$spans"/>
</xsl:apply-templates>
</tr>
<xsl:if test="following-sibling::row">
<xsl:apply-templates select="following-sibling::row[1]">
 <xsl:with-param name="spans">
    <xsl:apply-templates select="entry[1]" mode="span">
       <xsl:with-param name="spans" select="$spans"/>
    </xsl:apply-templates>
 </xsl:with-param>
</xsl:apply-templates>
</xsl:if>
</xsl:template>

<xsl:key name="colname" match="colspec" use="@colname"/>

<xsl:template match="entry" name="entry">
<xsl:param name="col" select="1"/>
<xsl:param name="spans" />
<xsl:message>
======================
Row: <xsl:value-of select="1+count(../preceding-sibling::row)"/>
Entry: <xsl:value-of select="1+count(preceding-sibling::entry)"/>
Column: <xsl:value-of select="$col"/>
Spans:<xsl:value-of select="$spans"/>
</xsl:message>
<xsl:if test=" $col > 10">
<xsl:message terminate="yes"> Panic </xsl:message>
</xsl:if>
<xsl:choose>
<xsl:when test="not(starts-with($spans,'0'))">
<xsl:message>
spanned entry
</xsl:message>
<xsl:call-template name="entry">
 <xsl:with-param name="col" select="$col+1"/>
 <xsl:with-param name="spans" select="substring($spans,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="key('colname',@namest)/@colnum &gt; $col">
<xsl:message>
 inserting entry in column <xsl:value-of 
select="$col"/> (&lt; <xsl:value-of select="key('colname',@namest)/@colnum"/>)
</xsl:message>
<td class="auto-generated">.</td>
<xsl:call-template name="entry">
 <xsl:with-param name="col" select="$col+1"/>
 <xsl:with-param name="spans" select="substring($spans,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message>
 Copy cell
</xsl:message>
 <td>
  <xsl:if test="@morerows>0">
   <xsl:attribute name="rowspan">
    <xsl:value-of select="1+@morerows"/>
   </xsl:attribute>
  </xsl:if>
  <xsl:apply-templates/>
 </td>
  <xsl:choose>
  <xsl:when test="following-sibling::entry">
   <xsl:apply-templates select="following-sibling::entry[1]">
 <xsl:with-param name="col" select="$col+1"/>
 <xsl:with-param name="spans" select="substring($spans,2)"/>
  </xsl:apply-templates>
  </xsl:when>
  <xsl:otherwise>
   <xsl:for-each select="/descendant::*[position() &lt; string-length($spans)]">
<xsl:message>
  extra cell
</xsl:message>
<td class="auto-generated">.</td>
    </xsl:for-each>
  </xsl:otherwise>
  </xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>


<xsl:template match="entry" name="sentry" mode="span">
<xsl:param name="col" select="1"/>
<xsl:param name="spans" />
<xsl:message>
===SPAN===================
Row: <xsl:value-of select="1+count(../preceding-sibling::row)"/>
Entry: <xsl:value-of select="1+count(preceding-sibling::entry)"/>
Column: <xsl:value-of select="$col"/>
Spans:<xsl:value-of select="$spans"/>
</xsl:message>
<xsl:if test=" $col > 10">
<xsl:message terminate="yes"> Panic </xsl:message>
</xsl:if>
<xsl:choose>
<xsl:when test="not(starts-with($spans,'0'))">
<xsl:message>
spanned entry
</xsl:message>
<xsl:value-of select="substring($spans,1,1)-1"/>
<xsl:call-template name="sentry">
 <xsl:with-param name="col" select="$col+1"/>
 <xsl:with-param name="spans" select="substring($spans,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="key('colname',@namest)/@colnum &gt; $col">
<xsl:message>
 inserting entry in column <xsl:value-of 
select="$col"/> (&lt; <xsl:value-of select="key('colname',@namest)/@colnum"/>)
</xsl:message>
<xsl:text>0</xsl:text>
<xsl:call-template name="sentry">
 <xsl:with-param name="col" select="$col+1"/>
 <xsl:with-param name="spans" select="substring($spans,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message>
 Copy cell
</xsl:message>
  <xsl:value-of select="@morerows"/>
  <xsl:if test="not(@morerows)">0</xsl:if>
  <xsl:choose>
  <xsl:when test="following-sibling::entry">
 <xsl:apply-templates select="following-sibling::entry[1]" mode="span">
 <xsl:with-param name="col" select="$col+1"/>
 <xsl:with-param name="spans" select="substring($spans,2)"/>
   </xsl:apply-templates>
  </xsl:when>
 <xsl:otherwise>
  <xsl:value-of select="translate(substring($spans,2),'9876543210','8765432100')"/>
 </xsl:otherwise>
 </xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>


======================================







<table border="1">
   <tr>
      <td rowspan="2">A</td>
      <td>B</td>
      <td rowspan="2">C</td>
      <td>D</td>
   </tr>
   <tr>
      <td class="auto-generated">.</td>
      <td>E</td>
   </tr>
</table>









<table border="1">
   <tr>
      <td>A</td>
      <td>B</td>
      <td rowspan="3">C</td>
      <td rowspan="3">D</td>
   </tr>
   <tr>
      <td rowspan="3">E</td>
      <td>F</td>
      <td class="auto-generated">.</td>
      <td class="auto-generated">.</td>
   </tr>
   <tr>
      <td>G</td>
      <td class="auto-generated">.</td>
      <td class="auto-generated">.</td>
   </tr>
   <tr>
      <td>H</td>
      <td class="auto-generated">.</td>
      <td>I</td>
   </tr>
</table>











<table border="1">
   <tr>
      <td>A</td>
      <td rowspan="3">B</td>
      <td>C</td>
      <td rowspan="2">D</td>
   </tr>
   <tr>
      <td rowspan="2">E</td>
      <td>F</td>
      <td class="auto-generated">.</td>
   </tr>
   <tr>
      <td class="auto-generated">.</td>
      <td>G</td>
   </tr>
   <tr>
      <td>H</td>
      <td class="auto-generated">.</td>
      <td>I</td>
      <td>J</td>
   </tr>
</table>










<table border="1">
   <tr>
      <td rowspan="3">A</td>
      <td class="auto-generated">.</td>
      <td class="auto-generated">.</td>
      <td class="auto-generated">.</td>
   </tr>
   <tr>
      <td>B</td>
      <td class="auto-generated">.</td>
      <td>C</td>
   </tr>
   <tr>
      <td class="auto-generated">.</td>
      <td rowspan="2">D</td>
      <td class="auto-generated">.</td>
   </tr>
   <tr>
      <td class="auto-generated">.</td>
      <td class="auto-generated">.</td>
      <td>E</td>
   </tr>
</table>




======================================

_____________________________________________________________________
This message has been checked for all known viruses by Star Internet
delivered through the MessageLabs Virus Scanning Service. For further
information visit http://www.star.net.uk/stats.asp or alternatively call
Star Internet for details on the Virus Scanning Service.

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread