DanielderGrosse
DanielderGrosse

Reputation: 77

XSLT Difference between value-of select and variable select

I need to flip the elements of two nodes. Originally the variable were set with the following command:

    <xsl:variable name="matchesLeft" select="$questionObject/descendant::simpleMatchSet[position()=1]/simpleAssociableChoice"/>
    <xsl:variable name="matchesRight" select="$questionObject/descendant::simpleMatchSet[position()=2]/simpleAssociableChoice"/>

I now want to flip the variable with the following code:

    <xsl:variable name="matchesRight">
        <xsl:choose>
            <xsl:when test="$flippedQuestions='true'">
                <xsl:value-of select="$questionObject/descendant::simpleMatchSet[position()=2]/simpleAssociableChoice"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$questionObject/descendant::simpleMatchSet[position()=1]/simpleAssociableChoice"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

But it only get the value from the first element and not all elements in the node. How can I achive this?

Upvotes: 1

Views: 4607

Answers (2)

Michael Kay
Michael Kay

Reputation: 163468

The problem is that xsl:variable/@select gives you a node-set, but xsl:value-of turns a node-set into its string value. You want the node-set. In XSLT 1.0, an xsl:variable with content will always give you a result-tree-fragment; but in the select attribute you're confined to using XPath 1.0 which has no conditional expression.

The best solution of course is to move to XSLT 2.0 which solves all these problems. The number of valid reasons for staying with 1.0 is reducing all the time. If you do have to stay with 1.0, there are convoluted workarounds in XPath 1.0 for the absence of a conditional expression, such as the one shown by Dimitre.

Upvotes: 2

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243539

Use:

<xsl:variable name="matchesRight" select=
 "$questionObject/descendant::simpleMatchSet
                                  [1+($flippedQuestions='true')]
                                          /simpleAssociableChoice"/>

Explanation:

In XPath whenever a boolean value $someBVal is passed to a numeric operator such as +, the boolean is converted to a number (either 0 or 1) using number($someBVal).

By definition:

number(false()) = 0

and

number(true()) = 1

Thus

1+($flippedQuestions='true')

evaluates to 1 if the string value of flippedQuestions isn't the string "true" and the same expression evaluates to 2 if the string value of flippedQuestions is the string "true" .

Upvotes: 0

Related Questions