Score Table Transformation
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="student-index" match="student" use="@id"/>
<xsl:template match="/gradebook">
<ul>
<xsl:for-each select="task-list/task[@recorded='yes']">
<xsl:sort select="@date" order="descending"/>
<li><xsl:value-of select="@id"/>: <xsl:value-of select="."/>
[<xsl:value-of select="@date"/>]</li>
</xsl:for-each>
</ul>
<table border="1">
<!-- create headings which always exist... -->
<tr>
<th>ID</th>
<xsl:for-each select="task-list/task[@recorded='yes']">
<xsl:sort select="@date" order="descending"/>
<th><xsl:value-of select="@id"/></th>
</xsl:for-each>
</tr>
<xsl:apply-templates select="student">
<xsl:sort select="@id"/>
</xsl:apply-templates>
<tr><th>n</th>
<xsl:for-each select="task-list/task[@recorded='yes']">
<xsl:sort select="@date" order="descending"/>
<xsl:variable name="task-id" select="@id"/>
<td align="right">
<xsl:value-of
select="count(/gradebook/student/result[@ref=$task-id]/@score[number(.)=number(.)])"/>
</td>
</xsl:for-each>
</tr>
<tr><th>Average</th>
<xsl:for-each select="task-list/task[@recorded='yes']">
<xsl:sort select="@date" order="descending"/>
<xsl:variable name="task-id" select="@id"/>
<td align="right">
<xsl:value-of select="format-number(
sum(/gradebook/student/result[@ref=$task-id]/
@score[number(.)=number(.)]) div
count(/gradebook/student/result[@ref=$task-id]/
@score[number(.)=number(.)]), '#.##')"/>
</td>
</xsl:for-each>
</tr>
</table>
</xsl:template>
<xsl:template match="student">
<tr>
<td><xsl:value-of select="substring(@id,2,3)"/>-XX-X<xsl:value-of
select="substring(@id,10,3)"/></td>
<xsl:variable name="id" select="@id"/>
<xsl:for-each select="/gradebook/task-list/task[@recorded='yes']">
<xsl:sort select="@date" order="descending"/>
<xsl:variable name="ref" select="@id"/>
<xsl:call-template name="insert_score">
<xsl:with-param name="n"
select="key('student-index', $id)/result[@ref=$ref]/@score"/>
</xsl:call-template>
</xsl:for-each>
</tr>
</xsl:template>
<xsl:template name="insert_score">
<xsl:param name="n"/>
<xsl:choose>
<xsl:when test="$n != ''">
<td align="right"><xsl:value-of select="$n"/></td>
</xsl:when>
<xsl:otherwise>
<td><br /></td>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>