Is it possible to use a Dynamic xPath expression in a xslt style sheet?
Check out http://www.exslt.org/. Specifically look at the dynamic:evaluate module.
XSLT doesn't support dynamic evaluation of XPath - that's why you need to use an extension function like EXSLT's evaluate
to do it.
If you don't want to use extension functions (and there are good reasons not to), another possibility is to query the input document's DOM before you execute the transform, and pass the node-set into the transform as a parameter.
Edit
About those curly braces: Those are attribute value templates (AVTs). These are semantically equivalent in an XSLT transform:
<foo>
<xsl:attribute name="bar">
<xsl:value-of select="XPathExpression"/>
</xsl:attribute>
</foo>
<foo bar="{XPathExpression}"/>
The second is just a shortcut for the first.
About variables and parameters: Syntactically, there's no difference between a variable and a parameter; anywhere you reference $foo
in an XPath expression it will work the same whether foo
is defined by xsl:variable
or xsl:param
.
The difference between the two is how they get populated. Variables are populated in the xsl:variable
declaration. Parameters are declared in a named template using xsl:param
, but they're populated by whatever calls the named template, using xsl:with-param
, e.g.:
<xsl:call-template name="foo">
<xsl:with-param name="bar" select="XPathExpression"/>
</xsl:call-template>
<xsl:template name="foo">
<xsl:param name="bar"/>
...
The big honking exception to this is parameters that are a child of xsl:stylesheet
. There's no way to populate those parameters within the transform; those are populated externally, by whatever (environment-specific) mechanism is invoking the transform.
A pretty common use case is making up for the fact that XSLT doesn't have a system date function. So you'll see something like:
<xsl:stylesheet ...
<xsl:param name="system-date"/>
...
and then, when invoking the transform, something like this (in C#):
XsltArgumentList args = new XsltArgumentList();
args.AddParam("system-date", "", DateTime.Now.ToString("s"));
xslt.Transform(input, args, result);
Try some variation of this:
<xsl:if test="not($var_myparam = 'no'))">
</xsl:if>
The problem is in how XPath evaluates booleans. Any non-empty string will evaluate to true in XPath. Checkout this write-up about xpath booleans.
As for your other questions... Variables and parameters act the same as each other in XPath expressions. Both are referenced with the form $var.
For any XSLT attribute named "select," you don't need the brackets. The brackets are used in what are called "attribute value templates." You use them when XSLT is expecting a string, for example:
<xsl:template match="name-a">
<xsl:variable name="old-name" select="name(.)" />
<name-b old-name="{$old-name}" new-attribute="hello" />
</xsl:template>
The XSLT spec talks about AVTs, and so does this page.