I have this XML:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<Response>
<Result>
<Date Unix="1263340800">13 Jan 2010 00:00:00</Date>
<Column>
<Name>Small</Name>
<Value>100</Value>
</Column>
</Result>
<Result>
<Date Unix="1263427200">14 Jan 2010 00:00:00</Date>
<Column>
<Name>Small</Name>
<Value>100</Value>
</Column>
</Result>
<Result>
<Date Unix="1263485232">14 Jan 2010 16:07:12</Date>
<Column>
<Name>Normal</Name>
<Value>36.170537</Value>
</Column>
</Result>
<Result>
<Date Unix="1263513600">15 Jan 2010 00:00:00</Date>
<Column>
<Name>Small</Name>
<Value>100</Value>
</Column>
</Result>
</Response>
I want to present the data in this way:
<table>
<tr>
<th>Time</th>
<th>Small</th>
<th>Normal</th>
</tr>
<tr>
<td>13 Jan 2010 00:00:00</td>
<td class="class_Small">100</td>
<td class="class_Normal"></td>
</tr>
<tr>
<td>14 Jan 2010 00:00:00</td>
<td class="class_Small">100</td>
<td class="class_Normal"></td>
</tr>
<tr>
<td>14 Jan 2010 16:07:12</td>
<td class="class_Small"></td>
<td class="class_Normal">39.301737</td>
</tr>
<tr>
<td>15 Jan 2010 00:00:00</td>
<td class="class_Small">100</td>
<td class="class_Normal"></td>
</tr>
</table>
This is my current XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="Friendlies" match="Name" use="."/>
<xsl:template match="/">
<table>
<tr>
<th>Time</th>
<!-- Output the Column Names -->
<xsl:for-each select="//Column">
<!-- Only ouput the Name if it is the first occurence of this value -->
<xsl:if test="generate-id(Name) = generate-id(key('Friendlies',Name)[1])">
<th>
<xsl:value-of select="Name"/>
</th>
</xsl:if>
</xsl:for-each>
</tr>
<!-- Loop through all Results -->
<xsl:for-each select="//Result">
<xsl:variable name="UnixTimestamp" select="Date/@Unix"/>
<tr>
<td>
<xsl:value-of select="Date"/>
</td>
<xsl:for-each select="//Column">
<xsl:if test="generate-id(Name) = generate-id(key('Friendlies',Name)[1])">
<xsl:element name="td">
<xsl:attribute name="class">class_<xsl:value-of select="Name"/></xsl:attribute>
<xsl:value-of select="[Date/@Unix=$UnixTimestamp]/Value"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
The HTML structure is coming out ok. The only problem is that the values aren't coming out in the cells. I realise that <xsl:value-of select="[Date/@Unix=$UnixTimestamp]/Value"/>
is not a correct reference, because the Date element is actually at the same level as the Column element, and not within it. I can't think of how this should be done though.
Also, I'm not really sure if I'm using the best method for this because it seems like there would be an awful lot of looping happening for little output. As the XML gets bigger (much more Results, more Columns), I wonder whether there would be a performance impact.
Forgive me, I'm a bit of a newbie to XSL.
Thanks in advance.
Added after Tomalak's response
Some info about the XML:
- Any number of
<Column>
nodes within each<Result>
node - Only one
<Date>
node within each<Result>
node - Only one
<Name>
node within each<Column>
node - The value of the
<Name>
node can be anything, not just 'Small' or 'Normal'