views:

22

answers:

2

I want to select an element by index with the indexed number being passed in with a param, the param is being passed in via PHP. Here's what I am trying:

//PHP
$xslt->setParameter('','player',$player);
$xslt->importStylesheet( $XSL );
print $xslt->transformToXML( $data ); 

//xslt
<xsl:param name="player" data-type="number"/>

<template match="/">
    <xsl:value-of select="result[$player]/@name" />
</template>

And I know the value of the param is being passed correctly because I can just output the value of the param ($player) and it will output the correct value. If I hard code the indexed number "$player" to any number of index I want like below:

<template match="/">
    <xsl:value-of select="result[2]/@name" />
</template>

it works. So, what I am doing wrong here. Can you not use params/variables to select indexes?

+1  A: 

It may be evaluating the value of your xsl:param as a string, rather than a number. You can try explicitly converting it to a number using the number() function.

<xsl:value-of select="result[number($player)]/@name" />

The predicate filter specifying a number is short-hand for [position()=$param]. You can use xsl:param inside the predicate filter, like this, and it will evaluate the xsl:param value as a number:

<xsl:value-of select="result[position()=$player]/@name" />
Mads Hansen
+1  A: 

If I hard code the indexed number "$player" to any number of index I want like below:

<template match="/"> 
    <xsl:value-of select="result[2]/@name" /> 
</template>

it works.

No, any compliant XSLT processor will not select anything.

result[2]/@name

is a relative expression against the current node, and the current node is the / -- document-node.

Any well-formed XML document has exactly one top element (never two), therefore

result[2]

is equivalent to:

/result[2]

and doesn't select anything.

Most probably you are dealing with another expression, which you haven't shown (or the template is not matching just /).

Also:

<xsl:param name="player" data-type="number"/>

this is invalid syntax. The <xsl:param> instruction doesn't have a data-type attribute.

In fact, in XSLT 1.0 there isn't any way to specify the type of variables or parameters.

This is why in:

result[$player]/@name

$player is treated as string -- not as an integer.

To achieve the "indexing" you want, use:

result[position()=$player]/@name

The position() function returns a number and this causes the other operand of the = operator to be converted to (and used as) number.

Dimitre Novatchev