Hi,
Note: I use xslt 1.0 and msxml
I have read the article on
http://www.jenitennison.com/xslt/grouping regarding grouping and also Michael Kay's XSLT Programmer's Reference book 1.0 to find out how to use this technique to speed up my transformation.
However, I am still not sure how to apply this technique to my xml.
The xml below is just an extract of my real xml. In this sample I only add the columns section but the same model applies to the rows as well.
My xslt (please see below) works fine but unfortunately with a large xml it can be very slow.
I would really appreciate if you could send me some sample code based on my xml or change the xslt pasted below.
The measures node on my xml represent the dimension of my table.
Cheers
CPall
XML
===
<?xml version="1.0"?>
<Reports xmlns="">
<Report>
<Measures>
<Measure idx="1" heading="Total Pages"/>
<Measure idx="2" heading="Cost"/>
</Measures>
<Columns>
<ColGrp heading="Year">
<Col heading="2003"/>
<Col heading="2004"/>
</ColGrp>
</Columns>
<Rows>
<RowGrp heading="Journal Group Name">
<Row heading="Gastroenterology">
<Cell/>
<Cell>
<Msr idx="1" val="42.00"/>
<Msr idx="2" val="64230"/>
</Cell>
</Row>
<Row heading="Other Specialty">
<Cell/>
<Cell>
<Msr idx="1" val="36.00"/>
<Msr idx="2" val="35820"/>
</Cell>
</Row>
<Row heading="Pharmacy">
<Cell>
<Msr idx="1" val="14.20"/>
<Msr idx="2" val="128030"/>
</Cell>
<Cell/>
</Row>
</RowGrp>
<RowGrp heading="">
<Row heading="Totals">
<Cell>
<Msr idx="1" val="14.20"/>
<Msr idx="2" val="128030.00"/>
</Cell>
<Cell>
<Msr idx="1" val="78.00"/>
<Msr idx="2" val="100050.00"/>
</Cell>
</Row>
</RowGrp>
</Rows>
</Report>
</Reports>
XSLT
====
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="iso-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="axisHeads" select="'false'" />
<xsl:variable name="msrs">
<xsl:choose>
<xsl:when test="//Measure">
<xsl:value-of select="count(//Measure)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="msrsNodeSet" select="Reports/Report/Measures/Measure"/>
<xsl:template match="Report" >
<div id="g1" style="position: absolute; top: 0px; left: 0px; width: 400px; height: 12px">
<table class="grdTop" border="0" cellspacing="1" cellpadding="0">
<tbody>
<xsl:apply-templates select="Columns" />
</tbody>
</table>
</div>
</xsl:template>
<xsl:template match="text()"> </xsl:template>
<xsl:template match="ColGrp" mode="counter">
<xsl:param name="sofar" />
<xsl:choose>
<xsl:when test="Col">
<xsl:value-of select="number($sofar)+1" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="ColGrp[1]" mode="counter">
<xsl:with-param name="sofar" select="number($sofar)+1" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Columns">
<xsl:apply-templates select="ColGrp[1]" mode="Header">
<xsl:with-param name="depth">
<xsl:choose>
<xsl:when test="$axisHeads='true'">
<xsl:value-of select="0"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="ColGrp" mode="Header">
<xsl:param name="depth" />
<tr>
<xsl:for-each select="//ColGrp[count(ancestor::ColGrp)=$depth]">
<td colspan="{count(.//Col)*$msrs}" align="center" style="overflow:none">
<nobr>
<div>
<xsl:value-of select="@heading"/>
</div>
</nobr>
</td>
</xsl:for-each>
</tr>
<xsl:choose>
<xsl:when test="ColGrp">
<xsl:apply-templates select="ColGrp[1]" mode="Header">
<xsl:with-param name="depth" select="$depth+1" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="Col[1]" mode="colHead" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Col" mode="colHead">
<tr>
<xsl:for-each select="ancestor::Columns//Col">
<td colspan="{$msrs}" valign="top" align="center" style="overflow:none">
<nobr>
<div>
<xsl:value-of select="@heading"/>
</div>
</nobr>
</td>
</xsl:for-each>
</tr>
<tr valign="bottom">
<xsl:for-each select="//Col">
<xsl:apply-templates select="//Measures">
<xsl:with-param name="pos" select="position()" />
</xsl:apply-templates>
</xsl:for-each>
</tr>
</xsl:template>
<xsl:template match="//Measures">
<xsl:param name="pos" />
<xsl:for-each select="Measure">
<xsl:variable name="mPos">
<xsl:value-of select="position()" />
</xsl:variable>
<td align="center">
<nobr>
<div class="action" style="width:90px; overflow:none" onclick="sortFullGrid({$mPos}, {$pos}, '{@class}')">
<xsl:value-of select="@heading"/>
</div>
</nobr>
</td>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>