Re: [xsl] replacing repeating data in cells with cell spans

Subject: Re: [xsl] replacing repeating data in cells with cell spans
From: "cking" <cking@xxxxxxxxxx>
Date: Sat, 4 Sep 2004 02:20:04 +0200
Aaron Johnson wrote:
> I am trying to populate a timetable with XML data using XSL.
>
> The cells of the table are coded into the XSL. When an item appears in the
> timetable, if it occurs in one or more periods, the cells are populated with
> data. I would like to have it so that the data stretches across the cells
> and appears only once instead of repeating.

Hi Aaron,

Try this:
http://users.telenet.be/cking/webstuff/test/timetable/output.html

XSL: timetable.xsl

<?xml version="1.0" encoding="UTF-8"?>

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

 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
  doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
  />

 <xsl:variable name="student-name" select="normalize-space(/coursePlanner-3-2/students/student[1]/name)"/>

 <xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml";>
   <head>
    <title>Timetable: <xsl:value-of select="$student-name"/></title>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
    <xsl:call-template name="style"/>
   </head>
   <body>
    <xsl:apply-templates/>
    <xsl:call-template name="footer"/>
   </body>
  </html>
 </xsl:template>

 <xsl:template name="style">
  <style type="text/css">
   <xsl:comment>
    a:hover { background: #9fc; }
    .header { background: #ccc; }
    .activity { background: #ff9; }
    .small { font-size: 70%; }
    .link { font-size: 120%; font-family: sans-serif; }
   </xsl:comment>
  </style>
 </xsl:template>

 <xsl:template name="footer">
  <p class="link"><b><a href="timetable.xml">XML</a> | <a href="timetable.xsl">XSL</a></b></p>
 </xsl:template>

 <xsl:template match="coursePlanner-3-2">
  <p><b>Timetable: </b><xsl:value-of select="$student-name"/></p>
  <table border="1">
   <xsl:apply-templates select="timetable"/>
  </table>
 </xsl:template>

 <xsl:template match="timetable">
  <tr>
   <th class="header">Date</th>
   <xsl:apply-templates select="specificDayRange/specificDay[1]/specificPeriod" mode="header"/>
  </tr>
  <xsl:apply-templates select="specificDayRange/specificDay"/>
 </xsl:template>

 <xsl:template match="specificDay">
  <tr>
   <td class="header"><xsl:value-of select="@dayOfWeek"/></td>
   <xsl:apply-templates select="specificPeriod"/>
  </tr>
 </xsl:template>

 <xsl:template match="specificPeriod" mode="header">
  <th class="header">
   <xsl:value-of select="@startTime"/>
  </th>
 </xsl:template>

 <xsl:template match="specificPeriod">
  <xsl:variable name="idref" select="currentActivity/@idref"/>
  <xsl:variable name="end-number" select="number(following-sibling::specificPeriod[currentActivity[@idref=$idref and
@endsHere='true']]/@number)"/>
  <xsl:variable name="prev-start" select="preceding-sibling::specificPeriod[currentActivity][1]/currentActivity/@startsHere"/>
  <xsl:choose>
   <xsl:when test="currentActivity/@startsHere = 'true'">
    <xsl:variable name="colspan">
     <xsl:choose>
      <xsl:when test="$end-number > 0">
       <xsl:value-of select="$end-number - @number + 1"/>
      </xsl:when>
      <xsl:otherwise>
       <xsl:value-of select="count(following-sibling::specificPeriod) + 1"/>
      </xsl:otherwise>
     </xsl:choose>
    </xsl:variable>
    <td colspan="{$colspan}" class="activity">
     <xsl:apply-templates select="currentActivity"/>
    </td>
   </xsl:when>
   <xsl:when test="not(currentActivity) and not($prev-start = 'true')">
    <td>&#0160;</td>
   </xsl:when>
  </xsl:choose>
 </xsl:template>

 <xsl:key name="activities" match="/coursePlanner-3-2/activities/activity" use="@id"/>
 <xsl:key name="modules" match="/coursePlanner-3-2/modules/module" use="@id"/>

 <xsl:variable name="baseURL" select="'http://development.uwe.ac.uk:8001/modules/caslogin.asp?code='"/>

 <xsl:template match="currentActivity">
  <xsl:variable name="moduleCode" select="key('activities', @idref)/moduleRef/@idref"/>
  <xsl:variable name="moduleName" select="normalize-space(key('modules', $moduleCode)/hostKey)"/>
  <p class="small">
   <xsl:value-of select="$moduleCode"/>
  </p>
  <p>
   <xsl:value-of select="$moduleName"/>
  </p>
  <p>
   <a href="{concat($baseURL, $moduleName)}">
    <xsl:value-of select="normalize-space(key('activities', @idref)/name)"/>
   </a>
   <xsl:text> </xsl:text>
   <xsl:value-of select="normalize-space(key('activities', @idref)/description)"/>
  </p>
 </xsl:template>

</xsl:stylesheet>

Cheers,
Anton Triest

Current Thread