views:

9049

answers:

3

I'm trying to output a variable's literal string value, after it is being set depending on whether a node exists or not. I think the condition check logic is correct. But it is not outputing the values...

<xsl:variable name="subexists"/>

<xsl:template match="class">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
<xsl:choose>
 <xsl:when test="joined-subclass">
  <xsl:variable name="subexists" select="'true'"/>
 </xsl:when>
 <xsl:otherwise>
  <xsl:variable name="subexists" select="'false'"/>
 </xsl:otherwise>
</xsl:choose>
subexists: <xsl:value-of select="$subexists" />

I want it to output the literal string of either "true" of "false". But it is not outputing anything. Please help! Thank you!!!

+5  A: 

Your main problem is thinking that the variable you declared outside of the template is the same variable being "set" inside the choose statement. This is not how XSLT works, the variable cannot be reassigned. This is something more like what you want:

<xsl:template match="class">
  <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
  <xsl:variable name="subexists">
    <xsl:choose>
      <xsl:when test="joined-subclass">true</xsl:when>
      <xsl:otherwise>false</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  subexists:      <xsl:value-of select="$subexists" />
</xsl:template>

And if you need the variable to have "global" scope then declare it outside of the template:

<xsl:variable name="subexists">
  <xsl:choose>
     <xsl:when test="/path/to/node/joined-subclass">true</xsl:when>
     <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:template match="class">
   subexists:      <xsl:value-of select="$subexists" />
</xsl:template>
eddiegroves
+3  A: 

In XSLT the same <xsl:variable> can be declared only once and can be given a value only at its declaration. If more than one variables are declared at the same time, they are in fact different variables and have different scope.

Therefore, the way to achieve the wanted conditional setting of the variable and producing its value is the following:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes"/>

    <xsl:template match="class">
    <xsl:variable name="subexists">
      <xsl:choose>
       <xsl:when test="joined-subclass">true</xsl:when>
       <xsl:otherwise>false</xsl:otherwise>
      </xsl:choose>
     </xsl:variable>
     subexists:  <xsl:text/>    
     <xsl:value-of select="$subexists" />
    </xsl:template>
</xsl:stylesheet>

When the above transformation is applied on the following XML document:

<class>
 <joined-subclass/>
</class>

the wanted result is produced:

 subexists:  true
Dimitre Novatchev
+1  A: 

In this case no conditionals are needed to set the variable.

This one-liner XPath expression:

boolean(joined-subclass)

is true() only when the child of the current node, named joined-subclass exists and it is false() otherwise.

The complete stylesheet is:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:template match="class">
   <xsl:variable name="subexists"
        select="boolean(joined-subclass)"
   />

   subexists:  <xsl:text/>
   <xsl:value-of select="$subexists" />
 </xsl:template>
</xsl:stylesheet>

Do note the use of the XPath function boolean() in this expression to convert a node (or its absense) to one of the boolean values true() or false().

Dimitre Novatchev