Subject: Re: complicated xslt question
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Sun, 27 Apr 2008 16:49:02 +0530
|
Please try the below 1.0 stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" />
<xsl:template match="/stats">
<html>
<head>
<title/>
</head>
<body>
<xsl:for-each select="month">
<table>
<tr>
<td>
<xsl:value-of select="@name" />
</td>
</tr>
<tr>
<td/>
<xsl:for-each select="site[1]/@*[starts-with(name(),'v')]">
<td>
<xsl:value-of select="name()" />
</td>
</xsl:for-each>
</tr>
<xsl:for-each select="site">
<tr>
<td>
<xsl:value-of select="concat('site',@id)" />
</td>
<xsl:for-each select="@*[starts-with(name(),'v')]">
<td>
<xsl:value-of select="." />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
<tr>
<td>sum</td>
<xsl:for-each select="site[1]/@*[starts-with(name(),'v')]">
<td>
<xsl:value-of select="sum(../../site/@*[name() =
name(current())])" />
</td>
</xsl:for-each>
</tr>
</table>
</xsl:for-each>
<table>
<tr>
<td>SUMMARY</td>
</tr>
<xsl:for-each select="month[1]/site[1]/@*[starts-with(name(),'v')]">
<tr>
<td>
<xsl:value-of select="concat(name(),'_max')" />
</td>
<td>
<xsl:call-template name="max">
<xsl:with-param name="months" select="../../../month" />
<xsl:with-param name="v" select="name()" />
</xsl:call-template>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="max">
<xsl:param name="months" />
<xsl:param name="v" />
<xsl:for-each select="$months">
<xsl:sort select="sum(site/@*[name() = $v])" data-type="number"
order="descending" />
<xsl:if test="position() = 1">
<xsl:value-of select="sum(site/@*[name() = $v])" />
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I have tried to make the code generic, in a way that it doesn't assume
fixed no is <month> tags, <site> tags or vn attributes.
On 4/27/08, mike.shestakov@xxxxxxxxx wrote:
> Hi!
> I'm trying to write XSL for a statistics page. (see XML below)
> Each site has four values to analyse: v1, v2, v3 and v4.
>
> The result of the transformation should be a set of tables for each
> month and one summarizing table.
> First I need to calculate sum of each value. For example for March it
> is v1_sum=100+100.
> Next I need to find maximum value among summarized values of v1. This
> is v1_max=max(200,330)=330
> Here is an example:
>
>
> March
> | v1 v2 v3 v4
> -----------------------
> site1 | 100 200 300 400
> site2 | 100 200 300 400
> -----------------------
> sum | 200 400 600 800
>
>
> April
> | v1 v2 v3 v4
> -----------------------
> site1 | 110 210 310 410
> site2 | 110 210 310 410
> site2 | 110 210 310 410
> -----------------------
> sum | 330 630 930 1230
>
>
> SUMMARY
> -----------------------
> v1_max | 330
> v2_max | 630
> v3_max | 930
> v4_max | 1230
>
>
>
> I know how to find maximum among v1 values.
> <xsl:variable name="v1_max">
> <xsl:for-each select="month/@v1">
> <xsl:sort data-type="number" order="descending"/>
> <xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if>
> </xsl:for-each>
> </xsl:variable>
>
> But in the case described I need to find the max in the set of values
> that has to be built first. Does anyone have any suggestions how to do
> that?
> Thanks!
>
> XML
> *****************
> <?xml version="1.0" encoding="UTF-8"?>
> <stats>
> <month name="March, 2008">
> <site id="1" v1="100" v2="200" v3="300" v4="400"/>
> <site id="2" v1="100" v2="200" v3="300" v4="400"/>
> </month>
> <month name="April, 2008">
> <site id="1" v1="110" v2="210" v3="310" v4="410"/>
> <site id="2" v1="110" v2="210" v3="310" v4="410"/>
> <site id="3" v1="110" v2="210" v3="310" v4="410"/>
> </month>
> </stats>
--
Regards,
Mukul Gandhi
|