In XSLT how do you test to see if a variable exists?

Solution 1:

Considering the XSLT stylesheet as an XML DOM, a variable declaration element makes the variable visible to all following siblings and their descendants. This allows XSLT processors to statically analyze any XPath containing a variable reference to see if the variable exists; if the variable declaration exists on the preceding-sibling or ancestor axis, the variable reference is legal, otherwise it's not.

Note that this is entirely dependent on the structure of the XSLT, not the structure of the XML it's processing. The XSLT processor can and should produce an error if an XPath expression uses a variable that doesn't exist.

There's no way to check for this condition inside XSLT because this condition isn't legal within XSLT. The sitauation you described in your comment - "The idea is to set a flag variable if something is output and later on display a different message if nothing was output." - actually should result in a syntax error. For instance, if you do something like this:

<xsl:if test="some_condition">
   <!-- produce output here -->
   <xsl:variable name="flag">true</xsl:variable>
</xsl:if>
<!-- time passes -->
<xsl:if test="$flag='true'>
   <!-- wouldn't it be nice? -->
</xsl:if>

you'll get a syntax error: the second xsl:if element is neither a following sibling of the variable declaration nor one of their descendants.

Here's a technique I use a fair amount - this produces variable output based on a variety of different conditions that you don't want to re-check later:

<xsl:variable name="output">
   <xsl:if test="$condition1='true'">
      <p>condition1 is true</p>
   </xsl:if>
   <xsl:if test="$condition2='true'">
      <p>condition2 is true</p>
   </xsl:if>
   <xsl:if test="$condition3='true'">
      <p>condition3 is true</p>
   </xsl:if>
</xsl:variable>
<!-- we've produced the output, now let's actually *output* the output -->
<xsl:copy-of select="$output"/>
<!-- time passes -->
<xsl:if test="normalize-space($output) != ''">
   <p>This only gets emitted if $output got set to some non-empty value.</p>
</xsl:if>

Solution 2:

Asking this question indicates that you did not fully grasp the key point of XSLT. :-)

It's declarative: nothing can exist unless you declare it. You declare a variable, then it's there, you don't, then it's not.

Not once will there be the point where you have to wonder, while coding, if a certain variable exists.

XSLT has strict scoping rules, variables exist only within the scope of their parent element, (and not all elements can contain variables to begin with). Once you leave the parent element, the variable is gone.

So unless you specify your question/intent some more, the only valid answer is that the question is wrong. You cannot and do not need to check if a variable exists at run-time.

Solution 3:

XSL variables are strictly scoped, so you can't access them in sibling nodes, only in children. If you are dealing with params, you can use a global <xsl:param />.

See: http://www.stylusstudio.com/xsllist/199911/post30020.html