Daniel Metcalfe
Daniel Metcalfe

Reputation: 193

How Can I Test Whether a Variable Contains an Element Value or a String / Number Value? (XSL 1.0)

I would like to know how to test for whether a variable contains an element value or a simple string / number in XSL 1.0.

<xsl:choose>
    <xsl:when test="is the variable an element">
           <!-- do some stuff -->
    </xsl:when>
    <xsl:otherwise>
           <!-- do some other stuff -->
    </xsl:otherwise>
</xsl:choose>

More Detail About My Problem

I have an XSL similar to the one below. Sometimes the variable may be an element and sometimes that element may have no value (i.e. nil = "true"). This is why I use the $imAStringButICouldHaveBeenAnElementForAllYouKnow[normalize-space()] test to check that the element has a value.

However, running this XSL with Saxon 6.5.5 fails with 'The value is not a node-set'. I can see why, the variable is indeed not a node set; I need an additional check before this one to confirm whether or not the variable contains an appropriate value.

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:variable name="imAStringButICouldHaveBeenAnElementForAllYouKnow" select="'string'"/>

    <xsl:template match="/">
        <!-- If this is an element I want to know does it have a value? -->
        <xsl:if test="$imAStringButICouldHaveBeenAnElementForAllYouKnow[normalize-space()]">
            <!-- do some stuff -->
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 3

Views: 4186

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 116992

I don't think this is possible with XSLT 1.0 (I would welcome being proven wrong). Any node-set function that would work on an element, will result in a fatal error if applied to a string.

How do you get to a position where you don't know in advance what's in your variable? It seems to me the real problem is there.


Note that you can check for the existence of a text value, regardless of the variable content's type by using:

<xsl:if test="normalize-space($myVar)">

This will return true when the variable is a non-empty, non-whitespace-only string OR an element that has a non-empty, non-whitespace-only descendant text node.


Edit:

I haven't noticed you are using Saxon 6.5 (until Michael Kay pointed this out in his answer). In such case, you can take advantage of the EXSLT exsl:node-type() extension function which Saxon 6.5 supports, e.g.:

<xsl:if test="exsl:object-type($myVar)='string'">
    <!-- do something -->
</xsl:if>

or

<xsl:if test="exsl:object-type($myVar)='node-set'">
    <!-- do something -->
</xsl:if>

Upvotes: 4

Michael Kay
Michael Kay

Reputation: 163322

It can't be done in pure XSLT 1.0. If you are running Saxon 6.5.5 then it should be easy enough to switch to Saxon 9.5 and XSLT 2.0 which offers immense benefits, quite apart from the "instance of" operator which provides the solution to this problem.

Upvotes: 2

Related Questions