In XSLT how do you test to see if a variable exist

2019-01-09 07:48发布

问题:

When using XSLT how do you test to see if a locally scoped variable exists, or is this even possible?

回答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>


回答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.



回答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



回答4:

I don't think it's possible, but you're not likely to ever need it, because the variable doesn't exist unless you've declared it.



回答5:

If you have a variable, you can check it has something, or it "exists" by doing something like the following:

<xsl:choose>
    <xsl:when test="$myvar">
        This variable exists!
    </xsl:when>
    <xsl:otherwise>
        The variable doesn't exist :(
    </xsl:otherwise>
</xsl:choose>

As for its validity I cannot be certain. I will tell you however, that I do this in some of our systems at work ;)



回答6:

Best and fast idea to check walue if it's exist is to check it length

<xsl:if test="string-length(value/to/check)=0">

</xsl:if>


回答7:

In any programming language you'll have exactly the same behavior.

Take C#. Trying to reference an undeclared variable name results in an error message. This is definetely a programmer error.

Why would it be necessary that XSLT behaves in a different way?

As for thinking about "before" and "later", or about a variable that would have more than one value in order to denote in which "state" we are -- this all is not allowed in XSLT by definition -- and exactly the absence of such "features" is what makes XSLT the nice and ellegant functional language it is.



标签: xml xslt