xsl-list
[Top] [All Lists]

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

2007-02-21 18:18:29
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[(_at_)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[(_at_)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(_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>

--~------------------------------------------------------------------
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>
--~--



--~------------------------------------------------------------------
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>
--~--