Suresh
Suresh

Reputation: 1091

Populating a variable with xsl choose

<xsl:template match="/">
      <xsl:variable name="a" select="'a'"/>
      <xsl:variable name="b" select="'b'"/>
      <xsl:variable name="c" select="'c'"/>
      <xsl:variable name="result">
        <xsl:choose>
          <xsl:when test="$a !=''">
            <xsl:value-of select="$a"/>
          </xsl:when>
          <xsl:when test="$b !=''">
            <xsl:value-of select="$b"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$c"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

The result variable is populated, here i used the xsl choose statements. I just wanted to know if there is any other efficient or simple way to populate the result variable, based on the same logic as xsl choose.

Something like this

<xsl:variable name="result" select="$a | $b | $c" />

The above will work for nodesets, not for variables. Any inputs?xsl 1.0

Upvotes: 3

Views: 2257

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

Something like this

<xsl:variable name="result" select="$a | $b | $c" /> 

The above will work for nodesets, not for variables. Any inputs?xsl 1.0

This is wrong! The above result variable is defined to contain the union of three node-sets -- not just one of them, depending on whether some other(s) of them are empty.

A correct XPath expression in this case is:

$a | $b[not($a)] | $c[not($a | $b)]

When These three variables aren't node-sets but strings and if these string values can have any length (not only length of 1), the corresponding XPath expression is similar:

concat($a, 
       substring($b, 1 div ($a = '')), 
       substring($c, 1 div (concat($a, $b) = ''))
       )

Here we use the fact that:

substring($s, $k) is the empty string ''

whenever

$k >= string-length($s)

and

substring($s, 1) = $s

Also:

1 div false()

is positive Infinity

(false() is converted to 0 when used in arithmetic operations).

and by definition

positive Infinity > $k

for every integer $k.

Therefore,

substring($s, 1 div $somethingFalse) = ''

and

substring($s, 1 div $somethingTrue) = $s

Finally, if it is guaranteed that the three variables $a, $b and $c can have as value only a single character, than we can use just:

substring(concat($a, $b, $c), 1, 1)

Upvotes: 2

Martin Honnen
Martin Honnen

Reputation: 167571

Well if the variables are bound to nodesets then $a | $b | $c yields the union of those nodesets and not an alternative so I am not sure what you want to explain by presenting that example.

In your first code sample you have three variables with values of type string where each holds a single character so you might be able to do <xsl:variable name="result" select="substring(concat($a, $b, $c), 1, 1)"/> if a single character or an empty string is all you expect and you want to find the very first character in the "set" of variables. But in general XSLT 1.0 might require verbose xsl:choose/when/otherwise coding.

Upvotes: 1

Related Questions