tags:

views:

68

answers:

5

Dear all,

I was wondering if someone remembers how to write a shorter OR statements in XSLT. I'm sure there was a way but I can't remember.

So instead of

test="$var = 'text1' or $var = 'text2'"

I'd like to use a shorter version like test="$var =['text1','text2']" However, I can't remember or find the right shorthand syntax for such cases.

Would really appreciate if someone could help with that!

Many thanks

A: 

The [] operator only works on a nodeset. Maybe you're thinking of when you say something like [a|b] to select nodes from your nodeset that have a child element a or a child element b. But for string comparison I don't know of any way other than using "or".

tpr
+1  A: 

For string values as you appear to be using you can use a concat trick:-

test="contains('__text1____text2__', concat('__', $var, '__'))"

Not shorter for just two items but given 5 or more it starts to look better.

Having said that you probably can multi-line when using or's so it may be better just to use a series of or's:-

test = "
  $var = 'text1'
  or $var = 'text2'
  or $var = 'text3'
  or $var = 'text3'"

More text but clearer solution.

AnthonyWJones
+1  A: 

If you find that you do many comparisons against a fixed set of values, you can also do this:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:cfg="http://tempuri.org/config"
  exclude-result-prefixes="cfg"
>
  <xsl:output method="text" />

  <!-- prepare a fixed list of possible values; note the namespace -->
  <config xmlns="http://tempuri.org/config"&gt;
    <val>text1</val>
    <val>text2</val>
    <!-- ... -->
  </config>

  <!-- document('') lets you access the stylesheet itself -->
  <xsl:variable name="cfg" select="document('')/*/cfg:config/cfg:val" />

  <xsl:template match="/">
    <xsl:variable name="var" select="'text2'" />

    <!-- check against all possible values in one step -->
    <xsl:if test="$cfg[.=$var]">
      <xsl:text>Match!</xsl:text>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

The above would print

Match!
Tomalak
A: 

There is no 'contains' function for sequences, but you could use index-of or intersect:

fn:exists(('test1', 'test2') intersect $var))

or

fn:exists(fn:index-of(('test1', 'test2'), $var))

With only two strings, your original solution is shorter though.

Tim Jansen
+2  A: 

With XSLT 2.0 (but not with XSLT 1.0) you can do

<xsl:if test="$var = ('text1','text2')">

Maybe that is the syntax you are looking for.

Martin Honnen
This is what I needed! Thanks :) Was nearly there.
DashaLuna