Hemant Kumar
Hemant Kumar

Reputation: 4611

What is the difference between XSLT attributes when and if

What is the difference between two given below codes? Both codes checks whether an attribute exists in a tag or not:

<xsl:choose>
  <xsl:when test="string-length(DBE:Attribute[@name='s0SelectedSite']/node()) &gt; 0"> 
    <table>
        ...
    </table>
  </xsl:when>
  <xsl:otherwise>
    <table>
        ...
    </table>
  </xsl:otherwise>
</xsl:choose>

and

<xsl:if test="@Col1-AllocValue"> 
    <xsl:copy-of select="@Col1-AllocValue"/>
</xsl:if>

Upvotes: 23

Views: 21339

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

What is the difference between two given below codes? Both codes checks whether an attribute exists in a tag or not:

This isn't true:

  1. The first code fragment expresses an if ... then ... else action, while the second fragment expresses just an if ... action.

  2. The conditions tested for in the provided two code fragments -- within the xsl:when instruction and withinin the xsl:if instructions are different. In fact only the xsl:if (in the second code fragment) tests for existence of an attribute.

Upvotes: 1

Nim
Nim

Reputation: 33645

The choose allows you to test for multiple conditions and apply only when one matches (or a default case). With if you can test too, but they are tested independently and each matching case will have output.

Adding more details (sorry had to rush off)

choose allows you to test for multiple cases and only generate output in the case that one of the conditions match, or generate some default output. for example:

<xsl:choose>
  <xsl:when test='@foo=1'><!-- do something when @foo is 1--></xsl:when>
  <xsl:when test='@foo=2'><!-- do something when @foo is 2--></xsl:when>
  <xsl:when test='@foo=3'><!-- do something when @foo is 3--></xsl:when> 
  <xsl:otherwise><!-- this is the default case, when @foo is neither 1, 2 or 3--></xsl:otherwise>
</xsl:choose>

As you can see one of the "branches" will be taken depending on the value of @foo.

With if, it's a single test and generate output on the result of that test:

<xsl:if test='@foo=1'><!-- do this if @foo is 1--></xsl:if>
<xsl:if test='@foo=2'><!-- do this if @foo is 2--></xsl:if>
<xsl:if test='@foo=3'><!-- do this if @foo is 3--></xsl:if>

The complication here is the failure case - what happens when @foo is neither 1,2 or 3? This missing case is what is handled neatly by the choose - i.e. the ability to have a default action.

XSL also lacks the "else" that you find in most other languages, that allows you to provide an alternative action should the if test fail - and a choose with a single when and otherwise allows you to get around this, but in my example above, that would be horrible (to demonstrate why you would not do this..)

<xsl:choose>
  <xsl:when test='@foo=1'><!-- do something when @foo is 1--></xsl:when>
  <xsl:otherwise> <!-- else -->
    <xsl:choose>
      <xsl:when test='@foo=2'><!-- do something when @foo is 2--></xsl:when>
      <xsl:otherwise> <!-- else -->
        <xsl:choose>
          <xsl:when test='@foo=2'><!-- do something when @foo is 2--></xsl:when>
          <xsl:otherwise><!-- this is the case, when @foo is neither 1, 2 or 3--></xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:otherwise>
</xsl:choose>

Upvotes: 5

Maestro13
Maestro13

Reputation: 3696

Structure of choose is

<xsl:choose>
    <xsl:when test="a">A</xsl:when>
    <xsl:when test="b">B</xsl:when>
    <xsl:when test="c">C</xsl:when>
    <xsl:when test="...">...</xsl:when>
    <xsl:otherwise>Z</xsl:otherwise>
</xsl:choose>

which allows multiple checks and one operation to be performed for the first test evaluating to true. xsl:otherwise is for performing default actions when none of the checks evaluates to true; in particular this facilitates an if-then-else construction (just one xsl:when alternative plus an xsl:otherwise block).

It always astounded me that xsl:if did not allow for an xsl:else alternative, but as this is available in xsl:choose construct, I guess it was judged not to add it. Maybe the next XSLT version will incorporate an xsl:else?

For the rest, the tests in xsl:when and in xsl:if do exactly the same thing: check the condition.

Note that the structure of xsl:if is simply

<xsl:if test="a">A</xsl:if>

A single

<xsl:when test="a">A</xsl:when>

would be invalid: xsl:when element is always a child of xsl:choose. And xsl:choose may have children xsl:when and xsl:otherwise only.

Upvotes: 19

Related Questions