RE: [xsl] Using XPath in an xsl:param?

Subject: RE: [xsl] Using XPath in an xsl:param?
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Mon, 19 Jul 2004 08:52:30 +0100
> I need to be able to dynamically pass in the artist names to 
> use in the
> match="cd[$test]" template.  The first question is that the 
> select statement
> in the global param declaration seems to be interpreting the 
> XPath statement
> rather than treating it as a literal string.  It ends up 
> being evaluated as
> a boolean.  Is there any way to prevent this from happening 
> and keep it as a
> string value? 

Yes, you could put it in quotes. To evaluate it as an XPath expression, you
would then need to use an xx:evaluate() extension function, which not all
processors support.

> In addition, I get an error telling me that 
> <xsl:template
> match="cd[$test]"> does not support variables within the 
> expression.  I'm
> not sure if this is due to the interpretation of $test.

This is a restriction in XSLT 1.0, lifted in 2.0. You can get round it in
1.0 by moving the condition from the predicate of the match pattern to an
xsl:choose inside the template rule. But remember that you need to test not
the string value of the parameter, but the result of interpreting the string
value as an XPath expression, for which you need xx:evaluate.

> Is there any way to get around these issues?  Essentially I'm 
> looking for a
> way to pass in a dynamic array of variables and create the match=""
> statement dynamically.  Is this possible by passing the 
> values I need in as
> a delimited string like <xsl:param name="test" select="Bob Dylan|Tina
> Turner"/> and then splitting up the result?

You mean select="'Bob Dylan|Tina Turner'"/>

Yes, you can do that. In 2.0 it's easy, you can write

<xsl:if test="artist = tokenize($artist-list, '|')"

In fact, you could make the parameter a list of strings, and then you
wouldn't need to tokenize it:

<xsl:param ... select="'Bob Dylan', 'Tina Turner'"/>

In 1.0 it's more difficult, you will either need to use an extension
function to do the tokenizing (e.g. dyn:tokenize() in EXSLT) or to write a
recursive template of your own.

Michael Kay

Current Thread