Parameter passing to a call template in xsl
Greetings, I'm a bit new to XSL and had a question regarding call-templates and parameters.
Assume I have the following xml:
<rec>
<a>1</a>
<b>2</b>
<c>3</c>
(etc.)
</rec>
<rec>
<a>4</a>
<b>9</b>
<c>2</c>
(etc.)
</rec>
etc...
I am writing a call-template that will display a row () in a multirow html table. Each row needs to record the name, average, min, max, etc. of each field of the entire record set.
so I would like to call <xsl:call-template name="DisplayRow"> <xsl:with-param name="fieldname" sel开发者_JAVA技巧ect="??"/>
The call template will need to iterate through all the records to find avg, min, max, etc so I'm not sure what to pass in as the call parameter. I was hoping to be able to pass in the field name (a, b, c, etc) and have it work that way but am unable to get my code to compile when I do.
For instance, to find the max value of field 'a' I would do something like:
<xsl:for-each select="/Rec[a!='NaN']">
<xsl:sort data-type="number" select="a" order="ascending"/>
<xsl:if test="position()=1">
etc.
For Avg I would do (skipping NaN):
<xsl:value-of select="sum(/rec/a[number(.)=number(.)])
div count(/rec/a[number(.)=number(.)])"/>
etc.
I also need to print out the literal name (e.g. 'a') in the row.
TIA
What you would need to select for the value of the filedName
param depends on what you want to do inside of your template.
You could pass in the name of the element that you want to generate the summary information about: e.g. <xsl:with-param name="fieldname" select="'a'"/>
You can obtain that by using local-name()
: i.e. <xsl:with-param name="fieldname" select="local-name(.)"/>
(if the context is one of those elements)
If you want to generate summary info for each of the children of <rec>
, then you could do something like the following:
This stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:key name="names" match="/records/rec/*" use="local-name(.)"/>
<xsl:template match="/">
<table>
<tr>
<td>Name</td>
<td>Count</td>
<td>Min</td>
<td>Max</td>
<td>Avg</td>
</tr>
<xsl:for-each select="/records/rec/*[generate-id(.) = generate-id(key('names', local-name(.)))]">
<xsl:call-template name="displayRow">
<xsl:with-param name="fieldName" select="local-name(.)"></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="displayRow">
<xsl:param name="fieldName"/>
<tr>
<td>
<xsl:value-of select="local-name(/records/rec/*[local-name()=$fieldName])"/>
</td>
<td>
<xsl:value-of select="count(/records/rec/*[local-name()=$fieldName])" />
</td>
<td>
<xsl:for-each select="/records/rec/*[local-name()=$fieldName][number(.)!='NaN']">
<xsl:sort data-type="number" select="." order="ascending"/>
<xsl:if test="position()=1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</td>
<td>
<xsl:for-each
select="/records/rec/*[local-name()=$fieldName][number(.)!='NaN']">
<xsl:sort data-type="number" select="." order="descending"/>
<xsl:if test="position()=1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</td>
<td>
<xsl:value-of
select="sum(/records/rec/*[local-name()=$fieldName] [number(.)=number(.)])
div count(/records/rec/*[local-name()=$fieldName][number(.)=number(.)])"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
Run against this XML(sample XML wrapped in a document element to make it well-formed):
<records>
<rec>
<a>1</a>
<b>2</b>
<c>3</c>
(etc.)
</rec>
<rec>
<a>4</a>
<b>9</b>
<c>2</c>
(etc.)
</rec>
</records>
Produces the following output:
<?xml version="1.0" encoding="UTF-8"?>
<table>
<tr>
<td>Name</td>
<td>Count</td>
<td>Min</td>
<td>Max</td>
<td>Avg</td>
</tr>
<tr>
<td>a</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>2.5</td>
</tr>
<tr>
<td>b</td>
<td>2</td>
<td>2</td>
<td>9</td>
<td>5.5</td>
</tr>
<tr>
<td>c</td>
<td>2</td>
<td>2</td>
<td>3</td>
<td>2.5</td>
</tr>
</table>
精彩评论