xsl-list
[Top] [All Lists]

Re: replacing repeating data in cells with cell spans

2004-09-03 17:20:04
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[(_at_)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