Subject: RE: [xsl] sequence as function parameter From: "Fabien Tillier" <f.tillier@xxxxxxxx> Date: Mon, 4 Jul 2011 17:09:56 +0200 |
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@xxxxxxxxxxxxxxxxxxxx] Envoyi : lundi 4 juillet 2011 17:06 @ : xsl-list@xxxxxxxxxxxxxxxxxxxxxx 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@xxxxxxxxxxxxxxxxxxxx Legal business disclaimers: http://www.CraneSoftwrights.com/legal
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] sequence as function para, G. Ken Holman | Thread | [xsl] Java list extension, Geurt Lagemaat |
RE: [xsl] sequence as function para, Fabien Tillier | Date | [xsl] Java list extension, Geurt Lagemaat |
Month |