Hi,
My problem is that when loopoing over the unique keys, the
node returned is
always the first node matching the key, which makes sense,
but I need to
return the current node in order to get the correct value
into the grid.
I'm looking for something like:
ID X Y A B
r0001 123 456
r0002 1 789
r0003 45 3 2
r0004 67 89
Columns A and B should be reversed, as B appears before A in the example
document—unless you want a second sort key which sorts the columns in reverse
document order. Anyhow, e.g.
<xsl:template match="records">
<html>
<body>
<table border="1">
<thead>
<tr>
<th>ID</th>
<xsl:for-each select="record/test[generate-id(.) =
generate-id(key('test-by-name', name))]">
<xsl:sort select="count(key('test-by-name', name))"
data-type="number" order="descending"/>
<th>
<xsl:value-of select="name" />
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:for-each select="record">
<tr>
<th>
<xsl:value-of select="id"/>
</th>
<xsl:variable name="current" select="."/>
<xsl:for-each select="../record/test[generate-id(.) =
generate-id(key('test-by-name', name))]">
<xsl:sort select="count(key('test-by-name', name))"
data-type="number" order="descending"/>
<td>
<xsl:for-each select="$current/test[name = current()/name]">
<xsl:value-of select="value"/>
</xsl:for-each>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
If performance becomes a problem, write the column order into a variable as a
space separated name list, then go through that list with a recursive template
and output the cell values based on that
<xsl:template match="records">
<html>
<body>
<table border="1">
<xsl:variable name="columns">
<xsl:for-each select="record/test[generate-id(.) =
generate-id(key('test-by-name', name))]">
<xsl:sort select="count(key('test-by-name', name))"
data-type="number" order="descending"/>
<xsl:value-of select="name" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:variable>
<thead>
<tr>
<th>ID</th>
<xsl:call-template name="header">
<xsl:with-param name="columns" select="$columns"/>
<xsl:with-param name="header" select="true()"/>
</xsl:call-template>
</tr>
</thead>
<tbody>
<xsl:for-each select="record">
<tr>
<th>
<xsl:value-of select="id"/>
</th>
<xsl:call-template name="header">
<xsl:with-param name="columns" select="$columns"/>
</xsl:call-template>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="header">
<xsl:param name="columns" select="''"/>
<xsl:param name="header" select="false()"/>
<xsl:if test="$columns">
<xsl:choose>
<xsl:when test="$header">
<th>
<xsl:value-of select="substring-before($columns, ' ')"/>
</th>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="test[name = substring-before($columns, '
')]/value"/>
</td>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="header">
<xsl:with-param name="columns" select="substring-after($columns, ' ')"/>
<xsl:with-param name="header" select="$header"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Cheers,
Jarno