RE: [xsl] Passing variables into XSLT via parameters ... can't get it to work

Subject: RE: [xsl] Passing variables into XSLT via parameters ... can't get it to work
From: "Buchcik, Kasimier" <k.buchcik@xxxxxxxxxxxx>
Date: Tue, 23 May 2006 14:47:26 +0200
Hi,

> -----Original Message-----
> From: Duncan Anker [mailto:danker@xxxxxxxxxxxxx]
>
> Hi List,
>
> I have a setup where I want to store my HTML pages as XML and
> use XSLT
> to apply common layout features, e.g. headers and footers. I
> also need
> to pass dynamic data into some of the pages, and rather than process
> everything twice I (perhaps foolishly) thought I could use
> parameters to
> send the data in. So I have a $parameters variable which contains a
> string something like '<parameters><namespace variable1="value"
> variable2="value" /></parameters>'
>
> In my HTML fragments where I want to place a variable, I use
> a call-out like
>
> <variable name="namespace:variable1" />
>
> Then in my XSLT I have this:
> <xsl:template match="variable">
>   <xsl:variable name="a" select="substring-before(@name, ':')" />
>   <xsl:variable name="b" select="substring-after(@name, ':')" />
>     <xsl:value-of select="exslt:node-set($parameters)//*[name() =
> $a]/@*[name() = $b]" />
>  </xsl:template>
>
> [As an aside, I couldn't get the substring-before and -after to work
> directly in the XPath expression. Am I missing something, or do they
> need to be assigned to variables like that to be used?]

You probably missed to use the current() function; the context
node changes in predicate expressions.
Try with:
<xsl:value-of
  select="c:node-set($parameters)//*[name() =
           substring-before(current()/@name, ':')]/@*[name() =
           substring-after(current()/@name, ':')]" />

> This all seems to work well enough when the $parameters string is set
> inside the stylesheet, however when I try to pass it in as a global

The content of a xsl:param is a sequence constructor (or "template"),
and will generate a result tree fragment hold by the parameter
"$parameters":

<xsl:param name="parameters">
  <foo bar="my-value"/>
</xsl:param>

So it's a tree - with nodes and everything.

> parameter I get empty results. I know the string is making it
> in because
> <xsl:value-of select="$parameters" /> prints out the escaped string.
> What I can't figure out is why it is not being treated the
> same way as a
> local variable would be.

Libxslt has no support for passing in tree fragments as parameter
values.
If you pass something in, then it is treated as a string. Libxslt does
not
automagically parse the given string and convert it to a tree fragment.
Maybe you should open an enhancement request for this feature.

> Can anyone shed any light on this? I've spent 2 days banging my head
> against Google so far. I am trying to do this with PHP 5.1.4 compiled
> against libXML and lbXSLT, versions 2.6.23 and 1.1.15
> respectively. I'd
> like to finger PHP as the culprit, but I get the same results when
> running xsltproc over the documents.

If it's not too much overhead for you, then you could use the document()
function to obtain the tree containing your parameters.

Example:

"test.xsl"
----------
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <!--
    The default URI for the XML document containing parameters.
    Override it with an externally provided parameter value.
  -->
  <xsl:param name="parameters-uri">params.xml</xsl:param>

  <xsl:template match="variable">
    <xsl:variable name="parameters" select="document($parameters-uri)"/>
    <xsl:value-of select="$parameters//*[name() =
      substring-before(current()/@name, ':')]/@*[name() =
      substring-after(current()/@name, ':')]" />
  </xsl:template>

</xsl:stylesheet>

"params.xml"
------------
<?xml version="1.0"?>
<foo bar="my-value"/>

"variables.xml"
---------------
<?xml version="1.0"?>
<variable name="foo:bar"/>

Result of xsltproc:

xsltproc test.xsl variables.xml
<?xml version="1.0"?>
my-value

Regards,

Kasimier

Current Thread