3

Using XSLT 1.0, how do I check whether the value in the variable exists or not?

I am assigning the value to the variable initially from my XML data and then need to check whether it exits or not:

<xsl:variable name="DOC_TYPE">
  <xsl:value-of select="name(./RootTag/*[1])"/>
</xsl:variable>
<xsl:if test="string($DOC_TYPE) = ''">
  <xsl:variable name="DOC_TYPE">
    <xsl:value-of select="name(./*[1])"/>
  </xsl:variable>
</xsl:if>  

The above is not working as expected. What I need is if <RootTag> exists in my data then the variable should contain the child node below the <RootTag>. If <RootTag> does not exist then the DOC_TYPE should be the first Tag in my XML data.

Thanks for your response.

Tomalak
  • 332,285
  • 67
  • 532
  • 628

3 Answers3

9

You can't re-assign variables in XSLT. Variables a immutable, you can't change their value. Ever.

This means you must decide within the variable declaration what value it is going to have:

<xsl:variable name="DOC_TYPE">
  <xsl:choose>
    <xsl:when test="RootTag">
      <xsl:value-of select="name(RootTag/*[1])" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="name(*[1])" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

A few other notes:

  • this: './RootTag' is redundant. Every XPath you don't start with a slash is relative by default, so saying 'RootTag' is enough
  • this: <xsl:value-of select="name(*[1])"/> already results in a string (names are strings by definition), so there is no need to do <xsl:if test="string($DOC_TYPE) = ''"> , a simple <xsl:if test="$DOC_TYPE = ''"> suffices
  • to check if a node exists simply select it via XPath in a test="..." expression - any non-empty node-set evaluates to true
  • XSLT has strict scoping rules. Variables are valid within their parent elements only. Your second variable (the one within the <xsl:if>) would go out of scope immediately(meaning right at the </xsl:if>).
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Thanks a lot. I will try this way and let me know if I have an y question. –  Sep 28 '09 at 16:13
1

Try this

   <xsl:variable name="DOC_TYPE">
     <xsl:choose>
       <xsl:when test="/RootTag"><xsl:value-of select="name(/RootTag/*[1])"></xsl:value-of></xsl:when>
       <xsl:otherwise><xsl:value-of select="name(/*[1])"/></xsl:otherwise>
     </xsl:choose>
   </xsl:variable>
Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
0

It only exists if you have assigned it. There's no reason to test it for existence.

See also here

Community
  • 1
  • 1
Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
  • Thanks. But My requirement is sometime I get data like this Then I need the Variable name as Order. Sometime I get data like this mean without RootTag Then also my variable should contain value. How do I acheive this ? –  Sep 28 '09 at 15:31
  • In your example variable always exists, it's the content that may differ. But anyway, since Jim Garrison's suggestion seems to have worked for you, I believe you should accept his answer. – Michael Krelin - hacker Sep 28 '09 at 19:31