xsl-list
[Top] [All Lists]

RE: [xsl] sequence as function parameter

2011-07-04 10:10:05
Thank you for your didactic explanations, Ken. It will help me next time I am 
trying to complicate things :)

Regards,
Fabien


-----Message d'origine-----
De : G. Ken Holman [mailto:gkholman(_at_)CraneSoftwrights(_dot_)com] 
Envoyé : lundi 4 juillet 2011 17:06
À : xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Objet : Re: [xsl] sequence as function parameter

At 2011-07-04 16:46 +0200, Fabien Tillier wrote:
I am trying to create a simple function to multiply each item in a
sequence by each other (like a sum()).
My problem is that I am unable to have the parameter treated as a node
sequence (using saxon, so XSL2.0)

I have
<xsl:template name=" multiplie">

That is a template, not a function, so I'm guessing we aren't looking 
at the code that produced your result.  Perhaps you are simply 
calling the template from the function?

        <xsl:param name="serie"/>
        <xsl:param name="result" as="xs:double"/>

Doesn't this have an initial value of 1?  Your template won't work if 
you pass an initial sequence of only a single value because you are 
multiplying that by the result and the result has no value.

        <!--some test output -->
        <xsl:value-of select="$serie"/>-<xsl:value-of
select="$result"/>--
        ###<xsl:value-of select="count($serie)"/>###
        <!-- -->
        <xsl:choose>
                <xsl:when test="count($serie) gt 1">
                        <!-- make the multiplication between result and
the first item in the serie, then remove it and call again -->
                        <xsl:variable name="comp">
                                <xsl:value-of select="number($serie[1])
* $result"/>
                        </xsl:variable>

This is wastefully creating a node tree...

                        <xsl:call-template name=" multiplie">
                        <xsl:with-param name="serie"><xsl:copy-of
select="subsequence($serie,2)"/></xsl:with-param>

... as is this ...

                        <xsl:with-param name="result"><xsl:value-of
select="$comp"/></xsl:with-param>

... and that.

                        </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                        <xsl:value-of select="number($serie[1]) *
$result"/>

Here is where your template won't work if you pass it an initial 
sequence of a single value.

...
So, the part where I do a count gets me 1, when I should have 4...
I have tried with
<xsl:param name="serie" as="node()*"/> but I have an error message
XTTE0790: Required item type of first argument of multiplie() is node();
supplied
  value has item type xs:double

If you want to pass either nodes or atomic values then use:

   as="item()*"

I am a bit out of ideas....

I think you are looking too deep.  And certainly your use of XSLT 
constructs could be more streamlined.  I believe you can implement 
your requirement completely in a one-line template with one parameter.

Does the example below help?

. . . . . . . . Ken

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
   xmlns:f="urn:X-Fabien"
   version="2.0">

<xsl:template match="/">
?<xsl:variable name="seq" select="(6.8E-06,5.5E-06,7.1E-06,7.3E-06)"/>
Fabien's test: <xsl:value-of select="f:multiplie($seq)"/>
Ken's tests: <xsl:value-of select="f:multiplie((7))"/>
and: <xsl:value-of select="f:multiplie((1,2,3,4,5))"/>
</xsl:template>

<xsl:function name="f:multiplie">
   <xsl:param name="seq" as="item()+"/><!--at least one item in sequence-->
   <xsl:sequence select="if( count($seq)=1 ) then $seq
                         else $seq[1] * f:multiplie($seq[position()>1])"/>
</xsl:function>
</xsl:stylesheet>

--
Contact us for world-wide XML consulting & instructor-led training
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


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

<Prev in Thread] Current Thread [Next in Thread>