Compare node set against a string

Discussion in 'XML' started by ShaggyMoose, Mar 13, 2008.

  1. ShaggyMoose

    ShaggyMoose Guest

    I have a delimited string (value1, value2, value3 etc) and a node set
    (single value text nodes). I want to compare each node in the set
    against the string and return true when a match is found. If no match
    is found, return false. However, I can't work out a way to do this
    without the ability to re-assign variables or exit a loop early. This
    isn't something I have had to attempt using XSL before. Can anyone
    suggest a way to complete the template function below, or a better
    method? Thanks.

    <xsl:template name="has-value">

    <xsl:param name="strVals"/> <!-- Comma delimited string of user
    roles. -->
    <xsl:param name="setVals"/> <!-- Node set of roles to match. -->

    <xsl:for-each select="etVals">
    <xsl:if test="contains($strVals, .)">
    -- RETURN TRUE HERE --
    </xsl:if>
    </xsl:for-each>

    -- RETURN FALSE HERE --

    </xsl:template>
    ShaggyMoose, Mar 13, 2008
    #1
    1. Advertising

  2. ShaggyMoose wrote:
    > I have a delimited string (value1, value2, value3 etc) and a node set
    > (single value text nodes). I want to compare each node in the set
    > against the string and return true when a match is found. If no match
    > is found, return false. However, I can't work out a way to do this
    > without the ability to re-assign variables or exit a loop early. This
    > isn't something I have had to attempt using XSL before. Can anyone
    > suggest a way to complete the template function below, or a better
    > method? Thanks.
    >
    > <xsl:template name="has-value">
    >
    > <xsl:param name="strVals"/> <!-- Comma delimited string of user
    > roles. -->
    > <xsl:param name="setVals"/> <!-- Node set of roles to match. -->
    >
    > <xsl:for-each select="etVals">
    > <xsl:if test="contains($strVals, .)">
    > -- RETURN TRUE HERE --
    > </xsl:if>
    > </xsl:for-each>


    Well with XSLT 2.0 you can easily do e.g.
    <xsl:value-of
    select="if ($setVals = tokenize($strVals, ',\s*')) then 'TRUE' else
    'FALSE'"/>

    For XSLT 1.0 check whether an EXSLT extension function can do the same:
    http://www.exslt.org/str/functions/tokenize/index.html



    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Mar 13, 2008
    #2
    1. Advertising

  3. ShaggyMoose

    ShaggyMoose Guest

    On Mar 13, 3:37 pm, Martin Honnen <> wrote:
    > Well with XSLT 2.0 you can easily do e.g.
    >    <xsl:value-of
    >      select="if ($setVals = tokenize($strVals, ',\s*')) then 'TRUE' else
    > 'FALSE'"/>


    Thanks for the reply Martin. However, the test you described will
    check that each node of the set matches each token from the string,
    correct? I only need to match one node from the set.
    ShaggyMoose, Mar 13, 2008
    #3
  4. In 1.0, I'd recursively parse my way through the string, extracting the
    values in order to do the appropriate comparisons.

    In general, if loops don't seem to do it for you in XSLT, consider
    recursion.

    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
    Joseph Kesselman, Mar 13, 2008
    #4
  5. ShaggyMoose

    Pavel Lepin Guest

    ShaggyMoose <> wrote in
    <>:
    > On Mar 13, 3:37 pm, Martin Honnen <>
    > wrote:
    >> Well with XSLT 2.0 you can easily do e.g.
    >> <xsl:value-of
    >> select="if ($setVals = tokenize($strVals, ',\s*')) then
    >> 'TRUE' else 'FALSE'"/>

    >
    > Thanks for the reply Martin. However, the test you
    > described will check that each node of the set matches
    > each token from the string, correct? I only need to match
    > one node from the set.


    XSLT1 should suffice:

    <xsl:template name="check-roles">
    <xsl:param name="string"/>
    <xsl:param name="nodeset"/>
    <xsl:choose>
    <xsl:when
    test=
    "
    $nodeset
    [
    contains(concat(', ',$string,', '),
    concat(', ',.,', '))
    ]
    ">
    <true/>
    </xsl:when>
    <xsl:eek:therwise>
    <false/>
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:template>

    Note that you made a standard beginner mistake: for-each is
    not a loop, it's an application of an inline template to a
    nodeset or a sequence. There's no order-of-execution
    guarantee.

    There aren't any loops in XSLT. If you need to iterate over
    some sort of collection, be it a nodeset, a tokenized
    string or anything else, you should use recursion. If it
    gets too deep, use divide-and-conquer or tail recursion
    (assuming your processor can optimise it away - some
    can't).

    --
    In Soviet Russia, XML documents transform *you*.
    Pavel Lepin, Mar 14, 2008
    #5
  6. ShaggyMoose wrote:
    > On Mar 13, 3:37 pm, Martin Honnen <> wrote:
    >> Well with XSLT 2.0 you can easily do e.g.
    >> <xsl:value-of
    >> select="if ($setVals = tokenize($strVals, ',\s*')) then 'TRUE' else
    >> 'FALSE'"/>

    >
    > Thanks for the reply Martin. However, the test you described will
    > check that each node of the set matches each token from the string,
    > correct? I only need to match one node from the set.


    No, the comparison
    $setVals = tokenize($strVals, ',\s*')
    compares two sequences and the general comparison is true if there is
    (at least) one value in the first that is equal to (at least) one value
    in the second sequence.

    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Mar 14, 2008
    #6
  7. ShaggyMoose

    ShaggyMoose Guest

    Thank you Martin and Pavel for your responses. I have managed to
    cobble together something that works.
    ShaggyMoose, Mar 14, 2008
    #7
    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. Replies:
    0
    Views:
    1,413
  2. Tjerk Wolterink
    Replies:
    2
    Views:
    1,404
    Dimitre Novatchev
    Aug 24, 2006
  3. Replies:
    0
    Views:
    511
  4. jiing
    Replies:
    0
    Views:
    2,304
    jiing
    Apr 27, 2007
  5. Mirovk
    Replies:
    1
    Views:
    268
    Mirovk
    Sep 12, 2006
Loading...

Share This Page