Variables in xpath expressions
Solution 1
<xsl:variable name="dayOfWeekIndex">
<xsl:choose>
<xsl:when test="lower-case($dayOfWeek) = 'monday'">
<xsl:value-of select="number(1)" />
</xsl:when>
....
An <xsl:variable>
with content but no as
attribute will set the variable to a "temporary tree", not a number, so a predicate [$dayOfweekIndex]
is treated as a boolean predicate rather than a restriction on the nodes' position()
. You need to add as="xs:integer"
to the xsl:variable
tag to force the variable to have the correct type.
Alternatively, use a select
instead, with the if
construct in XPath 2.0:
<xsl:variable name="dayOfWeekIndex" as="xs:integer" select="
if (lower-case($dayOfWeek) = 'monday') then 1 else
if (lower-case($dayOfWeek) = 'tuesday') then 2 else
.....
if (lower-case($dayOfWeek) = 'sunday') then 7 else
0" />
Solution 2
It matters how you set up the variable or parameter obviously e.g. with
<xsl:variable name="index" select="4"/>
<xsl:apply-templates select="data/contents[$index]/content"/>
it should work (i.e. process the fourth contents
), with
<xsl:variable name="index">4</xsl:variable>
<xsl:apply-templates select="data/contents[$index]/content"/>
it doesn't work as the predicate expression is not of type xs:integer
, it is a non empty sequence of nodes.
Solution 3
As others have noticed, specifying the type of a variable really matters in XSLT 2.0.
In addition to this, this transformation shows how to use an XPath one-liner to produce the wanted result:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"/>
<xsl:variable name="vWeekDays" as="xs:string+" select=
"('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday')"/>
<xsl:template match="/">
<xsl:variable name="vdayOfWeek" select="'Friday'"/>
<xsl:sequence select="index-of($vWeekDays, lower-case($vdayOfWeek))"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied to any XML document (not used), the wanted, correct result is produced:
5
pethel
Updated on April 13, 2020Comments
-
pethel about 4 years
Is it not posssible to use xsl:variables in xpath expressions? I am sure that my variable has the correct value. Have tried it both as String and number. The first one works but the second one selects all contents nodes and not just the one with index 4.
<xsl:apply-templates select="data/contents[4]/content" > <xsl:apply-templates select="data/contents[$myVariable]/content" >
edit
<xsl:variable name="dayOfWeekIndex"> <xsl:choose> <xsl:when test="lower-case($dayOfWeek) = 'monday'"> <xsl:value-of select="number(1)" /> </xsl:when> <xsl:when test="lower-case($dayOfWeek) = 'tuesday'"> <xsl:value-of select="number(2)" /> </xsl:when> <xsl:when test="lower-case($dayOfWeek) = 'wednesday'"> <xsl:value-of select="number(3)" /> </xsl:when> <xsl:when test="lower-case($dayOfWeek) = 'thursday'"> <xsl:value-of select="number(4)" /> </xsl:when> <xsl:when test="lower-case($dayOfWeek) = 'friday'"> <xsl:value-of select="number(5)" /> </xsl:when> <xsl:when test="lower-case($dayOfWeek) = 'saturday'"> <xsl:value-of select="number(6)" /> </xsl:when> <xsl:when test="lower-case($dayOfWeek) = 'sunday'"> <xsl:value-of select="number(7)" /> </xsl:when> </xsl:choose> </xsl:variable>