Click to See Complete Forum and Search --> : xsl param


spyro
05-25-2009, 06:20 PM
Hi, I am having difficulty displaying a variable to represent the percentage of students who receive a particular grade.
Any help would be greatly appreciated my code is as follows:

XML:
<student>
<first-name>Ulne</first-name>
<last-name>Douglas</last-name>
<grade>C</grade>
</student>
<student>
<first-name>Ambrose</first-name>
<last-name>Tyler</last-name>
<grade>B</grade>
</student>
<student>
<first-name>Roger</first-name>
<last-name>Clemens</last-name>
<grade>A</grade>
</student>
<student>
<first-name>Monroe</first-name>
<last-name>Hamburger</last-name>
<grade>A</grade>
</student>
</class>

XSL:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" />

<xsl:template name="print_grade">
<xsl:param name="target_grade" select="''" />
<xsl:variable name="grade" select="class/student[starts-with(grade,$target_grade)]" />
<xsl:if test="$target_grade=''" />
<h1><xsl:value-of select="$target_grade" /></h1>

<!--
Number of students receiving grade: <b><xsl:value-of select="count($grade)" /></b>

Percentage of students receiving grade: <!--I need to print the percentage of students receiving a particular grade variable out of the total students-->
-->
</xsl:template>

<xsl:template match="/">
<html>
<head>
<title>Grade Report</title>
</head>
<body>
<p>
<xsl:call-template name="print_grade">
<xsl:with-param name="target_grade" select="'A'"/>
</xsl:call-template>
</p>
<p>
<xsl:call-template name="print_grade">
<xsl:with-param name="target_grade" select="'B'"/>
</xsl:call-template>
</p>
<p>
<xsl:call-template name="print_grade">
<xsl:with-param name="target_grade" select="'C'"/>
</xsl:call-template>
</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

JohnBampton
05-26-2009, 06:54 AM
<xsl:value-of select="concat(count(class/student[grade = $target_grade]) div count(class/student) * 100,'%')"/>

Cheers, John Bampton

JohnBampton
05-26-2009, 07:16 AM
I would use XSLT 2.0 and do something like the following

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="/">
<html>
<head>
<title>Grade Report</title>
</head>
<body>
<p>
<xsl:for-each-group select="class/student" group-by="grade">
<xsl:sort select="grade"></xsl:sort>
<xsl:variable name="currentgrade" select="grade"></xsl:variable>
<h1>
<xsl:text> number of students receiving grade </xsl:text>
<xsl:value-of select="grade"></xsl:value-of>
<xsl:text> equals </xsl:text>
<xsl:value-of select="count(/class/student[grade = $currentgrade]) "></xsl:value-of>
<xsl:text> </xsl:text>
<xsl:text>Percentage </xsl:text>
<xsl:value-of select="concat(count(/class/student[grade = $currentgrade]) div count(/class/student) * 100,'%')"></xsl:value-of>
</h1>
<br/>
</xsl:for-each-group>
</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

This automatically picks up the grades without having to hard code them in the xsl in the call template.

Cheers, John Bampton.

JohnBampton
05-26-2009, 07:25 AM
Or you cound use XSL 1.0 with the following:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head>
<title>Grade Report</title>
</head>
<body>
<p>
<xsl:for-each select="class/student[not(grade = preceding::grade)]" >
<xsl:sort select="grade"></xsl:sort>
<xsl:variable name="currentgrade" select="grade"></xsl:variable>
<h1>
<xsl:text> number of students receiving grade </xsl:text>
<xsl:value-of select="grade"></xsl:value-of>
<xsl:text> equals </xsl:text>
<xsl:value-of select="count(/class/student[grade = $currentgrade]) "></xsl:value-of>
<xsl:text> </xsl:text>
<xsl:text>Percentage </xsl:text>
<xsl:value-of select="concat(count(/class/student[grade = $currentgrade]) div count(/class/student) * 100,'%')"></xsl:value-of>
</h1>
<br/>
</xsl:for-each>
</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Regards, John Bampton.

spyro
05-26-2009, 05:09 PM
Thanks John i have adapted your solution and it works perfectly:

<xsl:variable name="percent" select="count($grade)" />

Percentage of students receiving grade:
<b><xsl:value-of select="number($percent) div count(//grade) * 100" />%</b>