I'm no HTML expert so I have to guess what the HTML code for that looks like: presumably what you have to do is along the lines
for-each time-slot
<tr>
for-each day-of-the-week
if there's a session starting at this time/day
then <td rowspan="length of session">
apply-templates select="session"
</td>
else if there's a session continuing at this time./day
then ()
else <td/>
</tr>
which seems to translate into code something like the following. Im going to assume for simplification that the start and end times are labelled by numbers 1,2,3 rather than strings s1,s2, e1, e2:
<xsl:for-each select="startTime/st">
<xsl:variable name="st" select="."/>
<tr>
<td><xsl:value-of select="."/></td>
<xsl:for-each select="week[1]/day">
<xsl:choose>
<xsl:when test="allocation/starts[@startTimeRef=$st]">
<xsl:variable name="alloc" select="allocation/starts[@startTimeRef=$st]"/>
<xsl:variable name="length" select="$alloc/ends/@endTimeRef - $alloc/starts/@startTimeRef + 1"/>
<td rowspan="{$length}">
<xsl:apply-templates select="$alloc"/>
</td>
</xsl:when>
<xsl:when test="alllocation[starts/@startTimeRef lt $st and ends/@endTimeRef ge $st]"/>
<xsl:otherwise><td/></xsl:otherwise>
</xsl:choose>
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference