For your modified problem description, you would need the following
XSLT stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:common="http://exslt.org/common"
exclude-result-prefixes="common"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="by-type" match="Record[class = 'placed']" use="type" />
<xsl:template match="/x">
<totals>
<xsl:variable name="rtf">
<xsl:for-each select="Records/Record[class =
'placed'][generate-id() = generate-id(key('by-type', type)[1])]">
<temp><xsl:value-of select="count(key('by-type', type)) *
../../vrType/option[(_at_)value = current()/type]/@benchmark1" /></temp>
</xsl:for-each>
</xsl:variable>
<benchmark val="{sum(common:node-set($rtf)/temp)}" />
</totals>
</xsl:template>
</xsl:stylesheet>
The XML file is:
<?xml version="1.0"?>
<x>
<Records>
<Record>
<type>1</type>
<class>unplaced</class>
<count>3</count>
</Record>
<Record>
<type>2</type>
<class>placed</class>
<count>1</count>
</Record>
<Record>
<type>2</type>
<class>unplaced</class>
<count>8</count>
</Record>
<Record>
<type>3</type>
<class>met45</class>
<count>1</count>
</Record>
<Record>
<type>3</type>
<class>placed</class>
<count>5</count>
</Record>
<Record>
<type>3</type>
<class>unplaced</class>
<count>14</count>
</Record>
</Records>
<vrType>
<option value="1" benchmark1="540.00" benchmark2="540.00"
benchmark3="720.00" />
<option value="2" benchmark1="1101.00" benchmark2="1101.00"
benchmark3="1468.00" />
<option value="3" benchmark1="1801.50" benchmark2="1801.50"
benchmark3="2402.00" />
</vrType>
</x>
Please note - Now, the key definition has changed.
You mentioned - If I change the '1' in generate-id(key('by-type',
@type)[1]) to '2'
Answer to this is - here 1 cannot be changed to 2. Having [1] is part
of standard Muenchian grouping algorithm.
I hope you can adapt this stylesheet to suit your needs.
On 2/21/07, Steve <subsume(_at_)gmail(_dot_)com> wrote:
Applying this I'm stumped. In my version I am parsing nodes with
class='placed'. You will notice in the $EMP XML there are 1 type 2s
and 5 type 3s. But the below XML only returns 1101 (only counts the 1
type=2).
If I change the '1' in generate-id(key('by-type', @type)[1]) to '2',
it counts the 5 type=3's
XML contents of $EMP
<Records>
<Record>
<type>1</type>
<class>unplaced</class>
<count>3</count>
</Record>
<Record>
<type>2</type>
<class>placed</class>
<count>1</count>
</Record>
<Record>
<type>2</type>
<class>unplaced</class>
<count>8</count>
</Record>
<Record>
<type>3</type>
<class>met45</class>
<count>1</count>
</Record>
<Record>
<type>3</type>
<class>placed</class>
<count>5</count>
</Record>
<Record>
<type>3</type>
<class>unplaced</class>
<count>14</count>
</Record>
</Records>
XML contents of $types
<vrType>
<option value="1" benchmark1="540.00"
benchmark2="540.00"
benchmark3="720.00" />
<option value="2" benchmark1="1101.00"
benchmark2="1101.00"
benchmark3="1468.00" />
<option value="3" benchmark1="1801.50"
benchmark2="1801.50"
benchmark3="2402.00" />
</vrType>
XSL-----
<td>
<xsl:variable name="rtfm">
<xsl:for-each select="$EMP[class='placed' and generate-id() =
generate-id(key('byType',type)[1])]">
<temp>
<xsl:value-of
select="sum(key('byType',current()/type)[class='placed']/count) *
$types/option[(_at_)value=current()/type]/@benchmark1" /></temp>
</xsl:for-each>
</xsl:variable>
$<xsl:value-of select="sum(msxsl:node-set($rtfm)/temp)" />
</td>
On 2/20/07, Mukul Gandhi <gandhi(_dot_)mukul(_at_)gmail(_dot_)com> wrote:
> Here is another possible solution (using node-set extension function):
>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> xmlns:common="http://exslt.org/common"
> exclude-result-prefixes="common"
> version="1.0">
>
> <xsl:output method="xml" indent="yes"/>
>
> <xsl:key name="by-type" match="contact" use="@type" />
>
> <xsl:template match="/x">
> <totals>
> <xsl:variable name="rtf">
> <xsl:for-each select="contacts/contact[generate-id() =
> generate-id(key('by-type', @type)[1])]">
> <temp><xsl:value-of select="count(key('by-type', @type)) *
> ../../types/type[(_at_)value = current()/@type]/@benchmark1" /></temp>
> </xsl:for-each>
> </xsl:variable>
> <benchmark val="{sum(common:node-set($rtf)/temp)}" />
> </totals>
> </xsl:template>
>
> </xsl:stylesheet>
>
> When the above stylesheet is applied to the following XML:
>
> <?xml version="1.0"?>
> <x>
> <types>
> <type value="1" benchmark1="540" />
> <type value="2" benchmark1="640" />
> <type value="3" benchmark1="740" />
> </types>
> <contacts>
> <contact type="1" />
> <contact type="2" />
> <contact type="3" />
> <contact type="3" />
> </contacts>
> </x>
>
> The output produced is:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <totals>
> <benchmark val="2660"/>
> </totals>
>
> On 2/20/07, Steve <stephen(_at_)yeago(_dot_)net> wrote:
> > I could do the following easily by making a recursive template and
> > then looping through the contacts, and passing on the corresponding
> > benchmark value. But could xsl:key make for a shorter, more elegant
> > solution?
> >
> > Instead of performing an addition for each <contact>, could I simply
> > sum() them at once, somehow?
> >
> > With the following XML
> >
> > <types>
> > <type value="1" benchmark1="540" />
> > <type value="2" benchmark1="640" />
> > <type value="3" benchmark1="740" />
> > </types>
> > <contacts>
> > <contact type="1" />
> > <contact type="2" />
> > <contact type="3" />
> > <contact type="3" />
> > </contacts>
> >
> > desired output:
> >
> > <totals>
> > <benchmark val='2660' />
> > </totals>
--
Regards,
Mukul Gandhi
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--