xsl:variable question

Discussion in 'XML' started by sylvain.loiseau, Feb 26, 2004.

  1. Hello

    Given a node set, I try to compute the total of the string-length
    value of each node.

    For instance, with :

    <xsl:for-each select="//q">
    <!-- the length of each node is compute with: -->
    <xsl:value-of select="string-length(.)" />
    </xsl:for-each>

    but how to get the total of the different values, since xsl:variable
    do not allow the modification of its value?

    Thanks,
    Sylvain
     
    sylvain.loiseau, Feb 26, 2004
    #1
    1. Advertising

  2. "sylvain.loiseau" <> wrote in message
    news:c1lj9m$knl$...
    > Hello
    >
    > Given a node set, I try to compute the total of the string-length
    > value of each node.
    >
    > For instance, with :
    >
    > <xsl:for-each select="//q">
    > <!-- the length of each node is compute with: -->
    > <xsl:value-of select="string-length(.)" />
    > </xsl:for-each>
    >
    > but how to get the total of the different values, since xsl:variable
    > do not allow the modification of its value?


    Copy all nodes into an the RTF contents of an xsl:variable, then just use
    the string-length() function:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:eek:utput method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
    <xsl:variable name="vPersons">
    <xsl:copy-of select="//person"/>
    </xsl:variable>

    <xsl:value-of select="string-length($vPersons)"/>
    </xsl:template>
    </xsl:stylesheet>

    when this transformation is applied to the following source.xml:

    <persons>
    <person name="pt" public="false">
    <password>asdf</password>
    </person>
    <person name="ab" public="true">xx</person>
    </persons>

    the wanted result is produced:

    6


    Hope this helped.


    Cheers,

    Dimitre Novatchev [XML MVP],
    FXSL developer, XML Insider,

    http://fxsl.sourceforge.net/ -- the home of FXSL
    Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html
     
    Dimitre Novatchev [MVP XML], Feb 26, 2004
    #2
    1. Advertising

  3. > Hope this helped.

    Yes it helped. Thanks !

    Sylvain
     
    sylvain.loiseau, Feb 26, 2004
    #3
  4. "sylvain.loiseau" <> wrote in message news:<c1lmo1$t2n$>...
    > > Hope this helped.

    >
    > Yes it helped. Thanks !
    >
    > Sylvain



    Another way to do this is by using the Tree Visitor pattern:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:eek:utput omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@* | node()" name="treeVisitor">
    <xsl:param name="ptxtLength" select="0"/>
    <xsl:variable name="vsubtreeLength">
    <xsl:choose>
    <xsl:when test="not(node())">0</xsl:when>
    <xsl:eek:therwise>
    <xsl:apply-templates select="node()[1]">
    <xsl:with-param name="ptxtLength"
    select="$ptxtLength"/>
    </xsl:apply-templates>
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:variable>

    <xsl:choose>
    <xsl:when test="following-sibling::node()">
    <xsl:apply-templates select="following-sibling::node()[1]">
    <xsl:with-param name="ptxtLength"
    select="$ptxtLength + $vsubtreeLength * (number(.) = number(.))"/>
    </xsl:apply-templates>
    </xsl:when>
    <xsl:eek:therwise>
    <xsl:value-of select="$vsubtreeLength"/>
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:template>

    <xsl:template match="node()[not(node()) and not(following-sibling::node())]">
    <xsl:param name="ptxtLength" select="0"/>
    <xsl:value-of select="$ptxtLength"/>
    </xsl:template>

    <xsl:template match="person">
    <xsl:param name="ptxtLength" select="0"/>

    <xsl:call-template name="treeVisitor">
    <xsl:with-param name="ptxtLength"
    select="$ptxtLength + string-length(.)"/>
    </xsl:call-template>
    </xsl:template>
    </xsl:stylesheet>

    When this transformation is applied on this source.xml:

    <persons>
    <person name="pt" public="false">
    <password>asdf</password>
    </person>
    <person name="ab" public="true">xx</person>
    </persons>

    the wanted result is obtained:

    6


    Cheers,

    Dimitre Novatchev [XML MVP],
    FXSL developer, XML Insider,

    http://fxsl.sourceforge.net/ -- the home of FXSL
    Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html
     
    Dimitre Novatchev, Feb 27, 2004
    #4
  5. "sylvain.loiseau" <> wrote in message
    news:c1lj9m$knl$...
    > Hello
    >
    > Given a node set, I try to compute the total of the string-length
    > value of each node.
    >
    > For instance, with :
    >
    > <xsl:for-each select="//q">
    > <!-- the length of each node is compute with: -->
    > <xsl:value-of select="string-length(.)" />
    > </xsl:for-each>
    >

    Hi,

    I've looked at the other solutions presented and I feel that even though
    they work, they really arent utilizing the functional programming paradigm.
    Here is my solution :

    <xsl:call-template name="accumulate">
    <xsl:with-param name="nodes" select="//q" />
    <xsl:with-param name="sum" select="0" />
    </xsl:call-template>

    .....and then define "accumulate" as :

    <xsl:template name="accumulate">
    <xsl:param name="nodes" />
    <xsl:param name="sum" />

    <xsl:choose>
    <xsl:when test = "count($nodes) &gt; 1">
    <xsl:call-template name="accumulate">
    <xsl:with-param name="nodes" select="$nodes[position() != 1]" />
    <xsl:with-param name="sum" select="$sum + string-length($nodes[1])" />
    </xsl:call-template>
    </xsl:when>
    <xsl:eek:therwise>
    <xsl:value-of select="$sum + string-length($nodes[1])" />
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:template>

    Regards,
    Kenneth
     
    Kenneth Stephen, Mar 1, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Karsten Weinert
    Replies:
    3
    Views:
    1,024
    Karsten Weinert
    Jul 5, 2004
  2. Vijay singh
    Replies:
    1
    Views:
    445
    Martin Honnen
    Nov 4, 2004
  3. MC
    Replies:
    1
    Views:
    7,295
    David Carlisle
    Mar 24, 2005
  4. Replies:
    1
    Views:
    3,636
    A. Bolmarcich
    May 27, 2005
  5. Replies:
    2
    Views:
    9,307
    Martin Honnen
    Sep 5, 2006
Loading...

Share This Page