This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Converting a string to node test
On Sat, 21 Apr 2001, davidc@nag.co.uk wrote:
>
>> Do you know the secret?
> this is a FAQ I think.
Argh. This is the kind of FAQ very hard to track (in which section(s) should
it fall?)
>> <xsl:copy-of select="$x[@$y=$z]/node()"/>
>
> @$y doesn't mean anything as you observed.
>
> If $y is a string with a name of an attribute then you can go
> <xsl:copy-of select="$x[@*[name()=$y and .=$z]]/node()"/>
Another nice version of Jeni's solution, thank you! It seems so simple once
someone shows you :-)
> but usually it's more fun to pass in the node you want rather than
> mess with names. Variables in XSLT are not restricted to strings
> so you can pass nodes around.
>
> You didn't show how you were calling your template but rather than pass
> <xsl:with-param name="x" select="foo"/>
> <xsl:with-param name="y" select="'attr'"/>
>
> you may be able to do
>
> <xsl:with-param name="x" select="foo"/>
> <xsl:with-param name="y" select="foo[@attr']/>
I like this solution, but I'm not sure it is easy to implement for me,
since I wanted the various parameters to come from different documents,
one of them being a configuration file. The variable y rather acts as a key
in the config file.
In case you are interested, here the relevant excerpt of the config file:
<preferred-order criterium="location">
<value>default</value>
<value>work</value>
<value>home</value>
<value when="travelling">transit</value>
</preferred-order>
The higher level call to the template (x becomes item and y becomes
criterium):
<xsl:variable name="selected-addresses">
<xsl:call-template name="preferred-item">
<xsl:with-param name="item" select="address"/>
<xsl:with-param name="criterium" select="'location'"/>
</xsl:call-template>
</xsl:variable>
And the recursive (wannabe generic) template itself:
<xsl:template name="preferred-item">
<xsl:param name="item"/>
<xsl:param name="criterium"/>
<xsl:param name="criterium-rank" select="1"/>
<xsl:variable name="current-preferred-criterium" select="$config-tree/preferred-order[@criterium=$criterium]/value[$criterium-rank]"/>
<xsl:variable name="hit">
<!-- Here was the problem you solved -->
<xsl:copy-of
select="$item[@*[local-name() = $criterium] = $current-preferred-criterium]/node()"/>
</xsl:variable>
<xsl:if test="not(xt:node-set($hit)/node())"><!-- nothing found ? -->
<xsl:call-template name="preferred-item">
<xsl:with-param name="item" select="$item"/>
<xsl:with-param name="criterium" select="$criterium"/>
<xsl:with-param
name="criterium-rank" select="$criterium-rank + 1"/>
</xsl:call-template>
</xsl:if>
<xsl:copy-of select="$hit"/>
</xsl:template>
If you see a way to make this a three lines template, please be diplomatic,
as I spend more hours on this that I expected :-))
Anyway, thanks again!
Xavier.
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list