1

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?

2 Answers2

2

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.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
0

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" .

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • I need the position()=2 and position()=1 could I combine this? – DanielderGrosse Sep 12 '12 at 12:11
  • @DanielderGrosse, I don't understand what you are saying. What exactly nodes must be selected? The code in the question uses `xsl:choose` which always copies one of the two alternatives. If you need *both* nodes selected, then you don't need to check any condition at all. – Dimitre Novatchev Sep 12 '12 at 12:18
  • Sorry for the confusing comment. You're explanation give the answer to me. Thanks alot. – DanielderGrosse Sep 12 '12 at 12:23