[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Obtaining sums


Subject: RE: [xsl] Obtaining sums
From: "Passin, Tom" <tpassin@xxxxxxxxxxxx>
Date: Mon, 16 Aug 2004 15:28:08 -0400

> From: michael.s.eberhart@xxxxxxxxxxx

> I can't seem to figure out how to get a list of sums for each state.
>

This kind of question used to get asked more often than it does now.
Maybe the FAQs are working!

> The data looks like this:
>
> <LEVEL name="AB">
>       <TYPE name="MK001">
>             <STATE name="MAINE">91</STATE>
>             <STATE name="ALASKA">73</STATE>
>             <STATE name="OHIO">128</STATE>
>       </TYPE>
> ...
> </LEVEL>
>

This is a grouping problem.  With xslt 1.0 you have to use one or
another  trick to group all the entries for a particular state together
so they can be summed.  The most common trick is to use a key and
generate-id to create a list of unique items - state names in this case.
Then you can sum them all.  Rather than critique your code, I'll just
show you how this other way looks -

<xsl:variable name='states' select='/LEVEL/TYPE/STATE'/>
<xsl:key name='states' match='STATE' use='@name'/>

<!-- Here we find the first of all states with the same name -->
<xsl:variable name='unique-states'
	select='/LEVEL/TYPE/STATE[generate-id() =
generate-id(key("states",@name)[1])]'/>

<xsl:template match="/LEVEL">
<results>
	<xsl:for-each select='$unique-states'>
		<xsl:variable name='state-entries'
			select='$states[@name = current()/@name]'/>
		<sum state='{@name}'>
			<xsl:value-of select='sum($state-entries)'/>
		</sum>
	</xsl:for-each>
</results>
</xsl:template>

> The output should appear as:
>
> MAINE ALASKA      OHIO
> 219   158         176


I didn't format it this way but you can modify the templates to get it.
BTW, when you send in a request for help, please try to remove
extraneous things, like all that html code.

Also BTW, you have a probably typo in the key name "LEVLE-KEY" (which I
assume you use somewhere else).

Cheers,

Tom P


Current Thread
Keywords