I'd like to use the value of an xslt parameter in an xpath expression. Specifically, as part of a not()
call in an <xsl:if
expression.
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- my_param contains a string '/foo/bar', passed in from ant -->
<!-- the 'no' is just a default value -->
<xsl:param name="my_param">no</xsl:param>
<xsl:variable name="var_myparam" select="$my_param" />
<!-- ... -->
<!-- this works -->
<xsl:if test="not(/foo/bar)" /> <!-- expression returns boolean true -->
<!-- ... -->
</xsl:if>
<!-- I can't figure out how to do this the right way -->
<!-- None of these appear to work -->
<xsl:if test="not($var_myparam)" /> <!-- expression returns boolean false -->
<!-- ... -->
</xsl:if>
<xsl:if test="not({$var_myparam})" /> <!-- complains Required attribute 'test' is missing -->
<!-- ... -->
</xsl:if>
<xsl:if test="not({$myparam})" /> <!-- complains Required attribute 'test' is missing -->
<!-- ... -->
</xsl:if>
<xsl:if test="not($myparam)" /> <!-- expression returns boolean false -->
<!-- ... -->
</xsl:if>
</xsl:transform>
I'm a little unclear on what the correct syntax is for creating a dynamic xpath expression in an xslt style sheet. I'm also a little fuzzy on the difference between a paramater, a variable, and how expanstion of both works. For example, with parameters, I know that sometimes I need the brackets, and sometimes I don't.
<!-- when creating an element, it seems I need brackets -->
<xsl:element name="{$my_param}" />
<!-- when selecting an element value for the output stream, no brackets are needed -->
<xsl:value-of select="$my_param"/>
Any general/specific help would be greatly appreciated.
Dynamic XPath evaluation is not possible in pure XSLT 1.0 or 2.0. Unfortunately, very few XSLT 1.0 processors implement dyn:evaluate (). II. Process the XML document with XSLT and generate a new XSLT file that contains the XPath expressions -- then execute the newly-generated transformation.
What is XPath? 1 XPath is a syntax for defining parts of an XML document 2 XPath uses path expressions to navigate in XML documents 3 XPath contains a library of standard functions 4 XPath is a major element in XSLT and in XQuery 5 XPath is a W3C recommendation More ...
Unfortunately, very few XSLT 1.0 processors implement dyn:evaluate (). II. Process the XML document with XSLT and generate a new XSLT file that contains the XPath expressions -- then execute the newly-generated transformation.
Definition of XSLT Variable. XSLT variable is defined as special tags used to declare a local or global variable that we make use of to store any values. The declared variables are referenced within an Xpath expression. Once it is set we cannot overwrite or update the variables. The scope of the element is done by the element that contains it.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With