|
Subject: Re: [xsl] job for xsl:key? (XSL 1.0 question) From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx> Date: Wed, 21 Feb 2007 23:06:11 +0530 |
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: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[@value = current()/type]/@benchmark1" /></temp>
</xsl:for-each>
</xsl:variable>
<benchmark val="{sum(common:node-set($rtf)/temp)}" />
</totals>
</xsl:template><?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>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.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[@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.mukul@xxxxxxxxx> 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[@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@xxxxxxxxx> 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
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] job for xsl:key? (XSL 1.0, Steve | Thread | [xsl] Re: job for xsl:key? (XSL 1.0, Steve |
| Re: [xsl] job for xsl:key? (XSL 1.0, Steve | Date | Re: [xsl] Filter out elements that , Mukul Gandhi |
| Month |