Re: [xsl] job for xsl:key? (XSL 1.0 question)

Subject: Re: [xsl] job for xsl:key? (XSL 1.0 question)
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Wed, 21 Feb 2007 17:17:58 -0800
Using FXSL the solution is straightforward.

This is the XSLT 2.0 solution using the FXSL 2 function f:transform-and-sum():

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:f="http://fxsl.sf.net/";
xmlns:func-transform="f:func-transform"
exclude-result-prefixes="f func-transform"

<xsl:import href="../f/func-transform-and-sum.xsl"/>

<xsl:output method="text"/>

   <xsl:template match="/">
     <xsl:value-of select=
     "f:transform-and-sum(f:usrTrans(), /*/*/contact)"/>
   </xsl:template>

   <xsl:function name="f:usrTrans" as="element()">
     <func-transform:func-transform/>
   </xsl:function>

   <xsl:template match="func-transform:*" mode="f:FXSL">
     <xsl:param name="arg1"/>
     <xsl:sequence select="$arg1/root()/*/*/type[@value =
$arg1/@type]/@benchmark1"/>
   </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided xml document
(corrected to make it well-formed:

<t>
	<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>
</t>

The wanted result is produced:

2660

Below is the corresponding XSLT 1.0 transformation, making use of the
FXSL 1.2 tranform-and-sum template:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:func-transform="f:func-transform"
exclude-result-prefixes="xsl func-transform"

  <xsl:import href="transform-and-sum.xsl"/>
  <xsl:output method="text"/>

<func-transform:func-transform/>

   <xsl:template match="/">
     <xsl:call-template name="transform-and-sum">
       <xsl:with-param name="pFuncTransform"
                       select="document('')/*/func-transform:*[1]"/>
       <xsl:with-param name="pList" select="/*/*/contact"/>
     </xsl:call-template>
   </xsl:template>

   <xsl:template match="func-transform:*">
     <xsl:param name="arg"/>
     <xsl:value-of
select="$arg/ancestor::node()[last()]/*/*/type[@value =
$arg/@type]/@benchmark1"/>
   </xsl:template>
</xsl:stylesheet>


Hope this helped.



-- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play



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>

Current Thread