Passing node-sets as parameters?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alfred Taylor

    Passing node-sets as parameters?

    I essentially need a countif() function for xsl. Something to where I could
    do countif(node-set, condition). Rather than try to get too extreme, i
    decided to just write one for my countif() with the condition hardcoded.
    (this was also my first venture into creating "functions" )

    Pseudo-code is essentially this: Look at the current node and check the
    condition. If the condition is true, call our function again with an
    incremented count. If false, call function with the same value. Once we
    reach the end of the node set, return the counter variable. The whole time
    we're passing around a node-set and a current index.

    My problem is that i get an error when i try to index into the node-set like
    this $node-set[$index]. It looks like when i call the template and pass in
    a node-set using the select attribute, it converts that node-set into a
    string? (according to some posts i've read) So ways around that were to
    use the mxsl:node-set(). The problem is i tried that and it didn't work.
    (I'm using .NET to do the transform)

    The other question I had was if i can even index into a node set like i'm
    doing? Or maybe there's a better alternative for what i'm trying to do?

    Thanks,
    -A

    -------- CODE
    <xsl:template name="countWage sGreaterZero">
    <xsl:param name="number" />
    <xsl:param name="index" select="1"/>
    <xsl:param name="count" select="0" />
    <xsl:choose>
    <xsl:when test="$index > count($number)" >
    <xsl:value-of select="$count" />
    </xsl:when>
    <xsl:otherwis e>
    <xsl:when test="$number[$index]/@Value > 0">
    <xsl:choose>
    <xsl:variable name="recursive _result">
    <xsl:call-template name="countWage sGreaterZero">
    <xsl:with-param name="number" select="$number " />
    <xsl:with-param name="index" select="$index + 1" />
    <xsl:with-param name="count" select="$count + 1" />
    </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$recurs ive_result" />
    </xsl:choose>
    <xsl:otherwis e>
    <xsl:variable name="recursive _result">
    <xsl:call-template name="countWage sGreaterZero">
    <xsl:with-param name="number" select="$number " />
    <xsl:with-param name="index" select="$index + 1" />
    <xsl:with-param name="count" select="$count" />
    </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$recurs ive_result" />
    </xsl:otherwise>
    </xsl:when>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>


  • Oleg Tkachenko [MVP]

    #2
    Re: Passing node-sets as parameters?

    Alfred Taylor wrote:
    [color=blue]
    > I essentially need a countif() function for xsl. Something to where I could
    > do countif(node-set, condition). Rather than try to get too extreme, i
    > decided to just write one for my countif() with the condition hardcoded.
    > (this was also my first venture into creating "functions" )[/color]

    Well, are you sure you can't do that with count() function?
    E.g. count(//employee[@wage>60000])

    The problem usually is with sum() function when one needs to get sum of
    calculated values. Then the simplest (but not the most effective)
    solution is using temporary tree of calculated values and then coverting
    it to nodeset using xxx:node-set function and summing. Other solution is
    recursive template just like yours, but instead of passing index,
    usually tail nodeset is passed (nodeset with no first node):
    <xsl:with-param name="nodes" select="$nodes[position()>1]"/>
    You may want to look at FXSL library where this ideas were developed
    much further.
    [color=blue]
    > My problem is that i get an error when i try to index into the node-set like
    > this $node-set[$index].[/color]

    Which error? Try $node-set[position()=$ind ex]

    --
    Oleg Tkachenko [XML MVP]

    Comment

    • Oleg Tkachenko [MVP]

      #3
      Re: Passing node-sets as parameters?

      Alfred Taylor wrote:
      [color=blue]
      > I essentially need a countif() function for xsl. Something to where I could
      > do countif(node-set, condition). Rather than try to get too extreme, i
      > decided to just write one for my countif() with the condition hardcoded.
      > (this was also my first venture into creating "functions" )[/color]

      Well, are you sure you can't do that with count() function?
      E.g. count(//employee[@wage>60000])

      The problem usually is with sum() function when one needs to get sum of
      calculated values. Then the simplest (but not the most effective)
      solution is using temporary tree of calculated values and then coverting
      it to nodeset using xxx:node-set function and summing. Other solution is
      recursive template just like yours, but instead of passing index,
      usually tail nodeset is passed (nodeset with no first node):
      <xsl:with-param name="nodes" select="$nodes[position()>1]"/>
      You may want to look at FXSL library where this ideas were developed
      much further.
      [color=blue]
      > My problem is that i get an error when i try to index into the node-set like
      > this $node-set[$index].[/color]

      Which error? Try $node-set[position()=$ind ex]

      --
      Oleg Tkachenko [XML MVP]

      Comment

      • Alfred Taylor

        #4
        Re: Passing node-sets as parameters?


        "Oleg Tkachenko [MVP]" <oleg@NO!SPAM!P LEASEtkachenko. com> wrote in message
        news:%232IbWYcX EHA.3476@tk2msf tngp13.phx.gbl. ..[color=blue]
        > Alfred Taylor wrote:
        >[color=green]
        > > I essentially need a countif() function for xsl. Something to where I[/color][/color]
        could[color=blue][color=green]
        > > do countif(node-set, condition). Rather than try to get too extreme, i
        > > decided to just write one for my countif() with the condition hardcoded.
        > > (this was also my first venture into creating "functions" )[/color]
        >
        > Well, are you sure you can't do that with count() function?
        > E.g. count(//employee[@wage>60000])[/color]

        I guess countif() was a bad example to use. It's essentially a
        countifAndSum() function. ;)
        [color=blue]
        >
        > The problem usually is with sum() function when one needs to get sum of
        > calculated values. Then the simplest (but not the most effective)
        > solution is using temporary tree of calculated values and then coverting
        > it to nodeset using xxx:node-set function and summing. Other solution is
        > recursive template just like yours, but instead of passing index,
        > usually tail nodeset is passed (nodeset with no first node):
        > <xsl:with-param name="nodes" select="$nodes[position()>1]"/>
        > You may want to look at FXSL library where this ideas were developed
        > much further.[/color]

        Ahh crap. Brings back bad memories of the days they taught me functional
        languages. Man, looks like i'll have to get myself back into that mindset.
        Thanks for reminding me on the different programming paradigms.

        As for using xxx:node-set(), i'm still have a terrible time getting it to
        work with the .NET transform. something as simple as this:

        -- SNIP

        <xsl:styleshe et xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="ur n:schemas-microsoft-com:xslt">
        <xsl:template match="/">
        <xsl:call-template name="testMe">
        <xsl:with-param name="param1" select="." />
        </xsl:call-template>
        </xsl:template>
        <xsl:template name="testMe">
        <xsl:param name="param1" />
        <xsl:value-of select="msxsl:n ode-set($param1)/Example/Element/@Value" />
        </xsl:template>
        </xsl:stylesheet>

        -- END

        I've read numerous other posts with people being able to use it
        successfully, but i must be missing something here.

        -A
        [color=blue]
        >[color=green]
        > > My problem is that i get an error when i try to index into the node-set[/color][/color]
        like[color=blue][color=green]
        > > this $node-set[$index].[/color]
        >
        > Which error? Try $node-set[position()=$ind ex]
        >
        > --
        > Oleg Tkachenko [XML MVP]
        > http://blog.tkachenko.com[/color]


        Comment

        • Oleg Tkachenko [MVP]

          #5
          Re: Passing node-sets as parameters?

          Alfred Taylor wrote:
          [color=blue]
          > As for using xxx:node-set(), i'm still have a terrible time getting it to
          > work with the .NET transform. something as simple as this:[/color]

          Here is a classical example of evaluating a sum of calculated values
          using temporary tree and xxx:node-set() function. It's very easy, but
          not the most effective way:

          <items>
          <item price="9.99" quantity="30">S crewdriver</item>
          <item price="29.99" quantity="10">H andsaw</item>
          <item price="49.99" quantity="15">E lectric drill</item>
          </items>

          <xsl:styleshe et version="1.0"
          xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
          xmlns:msxsl="ur n:schemas-microsoft-com:xslt"
          exclude-result-prefixes="msxsl ">
          <xsl:template match="/">
          <xsl:variable name="totals-rtf">
          <xsl:for-each select="/items/item">
          <t>
          <xsl:value-of select="@price* @quantity"/>
          </t>
          </xsl:for-each>
          </xsl:variable>
          <xsl:variable name="totals" select="msxsl:n ode-set($totals-rtf)/t"/>
          Total: <xsl:value-of select="format-number(sum($tot als), '##0.00')"/>
          </xsl:template>
          </xsl:stylesheet>

          PS. rtf means result-tree fragment, which is temporary tree type in XSLT
          1.0.
          --
          Oleg Tkachenko [XML MVP]

          Comment

          Working...