Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't my XSLT variables substituting their values?

I am trying to use XSLT variables and not having much success, hopefully I'm just doing something dumb.

I have the following code snippet:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xalan="http://xml.apache.org/xslt"
  version="1.0">

    <xsl:template match="/">
      <xsl:variable name="config" select="query/@config"></xsl:variable>

so I expect there to be a variable 'config' set to the value of the 'config' attribute of my top-level element 'query'.

I then try to use the variable later in my stylesheet, for example:

<a href="localhost/test?go">
    {$config}
</a>

but the output I see in my output HTML document is:

<a href="localhost/test?go">
    {$config}
</a>

so the value has not been substituted as I would have expected.

I think this is pretty much the simplest case there could be, so I'm doing domething stupid! Please help, thanks!


UPDATE thanks to all who responded, I misunderstood the different contexts of whether I was working in an attribute or outside. Sorted my problem out nicely!

If I could I would accept two answers, the one I have, and @Aaron Digulla's, which explained the attributes thing.

like image 362
brabster Avatar asked Mar 11 '09 12:03

brabster


People also ask

How do you reassign a variable value in XSLT?

Variables in XSLT are not really variables, as their values cannot be changed. They resemble constants from conventional programming languages. The only way in which a variable can be changed is by declaring it inside a for-each loop, in which case its value will be updated for every iteration.

How do you use equal in XSLT?

To see if two elements are the same, XSLT compares their string values using the equals sign ("="). To demonstrate several variations on this, our next stylesheet compares the a element in the following with its sibling elements.

How do I declare a global variable in XSLT?

XSLT <xsl:variable>The <xsl:variable> element is used to declare a local or global variable. Note: The variable is global if it's declared as a top-level element, and local if it's declared within a template. Note: Once you have set a variable's value, you cannot change or modify that value!

What is difference between Param and variable in XSLT?

The difference is that the value of an xsl:param could be set outside the context in which it is declared.


1 Answers

There are two questions here that seem the same, but which are subtly different: 1) How do I reference a variable by name? 2) Where can I reference a variable by name?

First, variables are always referenced using the $varname syntax. Second, this can be done anywhere an expression is allowed. It's the second part of this that seems to confuse. To start with, the value of an element or attribute will by default be output literally, so no variables are actually referenced in the following example:

<element attr="$test">$test or {$test}</element>

The output will literally match what was typed.

To output a variable's value, we need to reference it where an expression is allowed. In element content, we use xsl:value-of; in attributes that are treated as an Attribute Value Template (e.g. the attributes of a literal result element), expressions are delimited by curly braces {}. Assume the following declaration:

<xsl:variable name="test" select="'value'"/>

...then the following:

<element attr="{$test}"><xsl:value-of select="$test"/></element>

...results in:

<element attr="value">value</element>

A few parting notes on AVTs and value-of:

  • In both cases the variable was referenced as $test. The braces in an AVT are not part of the variable reference; they are expression delimiters.
  • In either case, the expression need not have contained a reference to a variable; any XPath expression would have been allowed.
  • Not all attributes in an XSLT document are treated as attribute value templates. For example, notice that xsl:value's select attribute already accepts an expression as content.
  • Question: Why can't you use value-of in an attribute, like this?

    <element attr="<xsl:value-of select="$test"/>"/>
    

    Answer: Because XSLT documents must contain well-formed XML (and that isn't).

  • Question: Why can't you use {$varname} in element content?

    Glib answer: because XSLT's creators didn't design it that way.

like image 140
Wayne Avatar answered Nov 15 '22 10:11

Wayne