joshp123
joshp123

Reputation: 77

Surprising XSLT/XPath expression type behavior

I ran into a behavior related to types in XSLT/XPath that I can't explain. Here's a snippet of XSLT that shows the problem (it's not a very useful XSLT, of course, but it represents a pretty minimal demonstration my question):

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <xsl:variable name="root">
                <xsl:sequence select="root(.)"/>
            </xsl:variable>
            <xsl:if test="root(.) is  $root">
                Match
            </xsl:if>
        </xsl:template>
    </xsl:stylesheet>

You will see that "Match" is not displayed. However, if you add as="node()" to the <xsl:variable name="root"> then "Match" is displayed.

Can anyone explain help me understand why?

You can plug this XSLT into http://xslttest.appspot.com to explore the problem. Any input XML will work (e.g., <?xml version="1.0"?><foo/>).

Thanks, Josh.

Upvotes: 3

Views: 136

Answers (1)

Linga Murthy C S
Linga Murthy C S

Reputation: 5432

To know the difference between a sequence and a variable you may go through the following link.

To summarize, xsl:variable without an as attribute creates a new document(having its own root node). Using as attribute helps creating an atomic value or a sequence. Here, the variable wouldn't be a root node but will refer to the sequence(s) it contains.

When you use:

<xsl:variable name="root">
            <xsl:sequence select="root(.)"/>
</xsl:variable>

With the condition <xsl:if test="root(.) is $root">, you are testing whether the root of the input XML document is same as the root of the variable root, which is false.

And when you use:

<xsl:variable name="root" as="node()">

The condition, root(.) is $root evaluates to true as both the input document root and the sequence generated by variable root are same.

And of course, as mentioned by michael.hor257k this stylesheet shall be versioned 2.0.

EDIT: Declaring variable in the following way would also make the condition true()

<xsl:variable name="root" select="root(.)"/>

Upvotes: 2

Related Questions