tags:

views:

236

answers:

3

How can I check whether the value of a string variable is Yes or No?

<xsl:variable name="test1" select="DBE:OBJECT/DBE:ATTRIBUTE[@name='test1']/DBE:String"/>
<xsl:variable name="test2" select="DBE:OBJECT/DBE:ATTRIBUTE[@name='test2']/DBE:String"/>

<xsl:choose>
<xsl:when test="$test1 = 'Yes'>
    <xsl:apply-templates select="YES"/>
</xsl:when>
<xsl:when test="$test2 = 'Yes'>
    <xsl:apply-templates select="Invalid"/>
</xsl:when>
<xsl:otherwise>
     <xsl:apply-templates select="DBE:OBJECT/DBE:ATTRIBUTE[@name='test3']/DBE:String"/>
</xsl:otherwise>
</xsl:choose>

Please let me know what is wrong in the above.

+2  A: 

Your problem isn't the when test, it's the <xsl:apply-templates select="YES"/> and <xsl:apply-templates select="Invalid"/>. The YES and Invalid won't correspond to anything -- there's no concept of constants in XSL, and it doesn't look like an XPath expression -- so there's nothing to apply to.

Instead, try something like this:

<xsl:variable 
  name="test1" 
  select="DBE:OBJECT/DBE:ATTRIBUTE[@name='test1']/DBE:String"
  />
<xsl:variable 
  name="test2" 
  select="DBE:OBJECT/DBE:ATTRIBUTE[@name='test2']/DBE:String"
  />

<xsl:choose>
  <xsl:when test="lower-case($test1) = 'yes'>
    <xsl:apply-templates 
      select="."
      mode="test-yes"
      />
  </xsl:when>
  <xsl:when test="lower-case($test2) = 'yes'>
    <xsl:apply-templates 
      select="."
      mode="test-invalid"
      />
  </xsl:when>
  <xsl:otherwise>
     <xsl:apply-templates 
      select="DBE:OBJECT/DBE:ATTRIBUTE[@name='test3']/DBE:String"
      />
  </xsl:otherwise>
</xsl:choose>

<xsl:template match="*" mode="test-yes">
  Yes!!!
</xsl:template>

<xsl:template match="*" mode="test-invalid">
  Invalid!!!
</xsl:template>

Also, keep in mind that variables can be "expensive" in XSL; the processing engine takes a full copy of the nodeset you're referencing, rather than just keeping a pointer, so you're carrying around the "weight" of the nodeset in memory while that part of the context is being processed. If you can do the test inline it's much better.

In fact, choose is relatively slow compared to the optimized flow of apply-templates. Your processing will be much faster. If you can be sure that only one of the tests will match it would be better to do something like this:

<xsl:apply-templates 
  mode="test-yes"
  select="
    DBE:OBJECT/DBE:ATTRIBUTE[@name='test1']/DBE:String[lower-case(.) = 'yes']
  " />

<xsl:apply-templates 
  mode="test-invalid"
  select="
    DBE:OBJECT/DBE:ATTRIBUTE[@name='test2']/DBE:String[lower-case(.) = 'yes']
  " />

  <xsl:apply-templates 
  mode="test-otherwise"
  select="
    DBE:OBJECT/DBE:ATTRIBUTE[@name='test2']/DBE:String
  " />

<xsl:template match="*" mode="test-yes">
  Yes!!!
</xsl:template>

<xsl:template match="*" mode="test-invalid">
  Invalid!!!
</xsl:template>

<xsl:template match="*" mode="test-otherwise">
  Something else!
</xsl:template>

If you can't be sure you can always add further tests "inline" to the apply-templates, for example:

<xsl:apply-templates 
  mode="test-yes"
  select="
    DBE:OBJECT/DBE:ATTRIBUTE[
      @name='test1'
    ]/DBE:String[
      lower-case(.) = 'yes'
      and
      not(
        lower-case(../DBE:ATTRIBUTE[@name='test2']/DBE:String/text()) = 'yes'
      )
    ]
  " />
<!-- etc... -->
digitala
Also, you have a 0% accept rating. Don't forget to accept the answer that is most helpful to you by clicking on the check-mark to the left! :D
digitala
lower-case is giving errorERROR: 'Error checking type of the expression 'funcall(lower-case, [step("self", -1)])'.'FATAL ERROR: 'Could not compile stylesheet'
prashant rao
try `fn:lower-case()` - your xsl engine might require the namespace "fn" to understand which function to execute.
digitala
A: 

Hi all, I tried lower-case

xsl:when test="$test1 = 'Yes' or 'Yes'">
  <td>
                       Yes
  </td>

xsl:when>

xsl:when test="$test2 = 'Yes' or 'yes'">
  <td>
                       INVALID
  </td>

xsl:when>

xsl:otherwise> 
  <td>
   <font size="2">
    f<xsl:apply-templates select="../DBE:Object/DBE:Attribute[@name='test1']"/> 
   </font>
  </td>
/xsl:otherwise>
 /xsl:choose>

But it is not evaluating the condition correctly. Please suggest the possible solution.

prashant rao
You should probably want to include this in an *edit to your question* in stead of an *answer*
Joren
+1  A: 

The element:

<xsl:apply-templates select="YES"/>

will attempt to find child elements of the current context whose qualified name is YES, i.e. it is looking for something like:

<YES ...>...</YES>

This is almost certainly not what you want. It's an easy mistake to make and I have made it frequently.

peter.murray.rust