Can i use xPath dynamic expression in xslt stylesheet?

I would like to use the value of the xslt parameter in the xpath expression. In particular, as part of a call to not() in the expression <xsl:if .

 <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 am a bit unclear regarding the correct syntax for creating a dynamic xpath expression in an xslt stylesheet. I'm also a bit vague in the difference between a parameter, a variable, and how both works expand. For example, with parameters, I know that sometimes I need brackets, and sometimes not.

 <!-- 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 is appreciated.

+6
xml xpath xslt ant
source share
3 answers

Check out http://www.exslt.org/ . In particular, look at the dynamic: evaluate the module.

+5
source share

XSLT does not support XPath dynamic evaluation - therefore, you need to use an extension function such as EXSLT evaluate .

If you do not want to use the extension functions (and there are good reasons not to do this), another option is to request the input DOM document before performing the conversion and pass node -set to the conversion as a parameter.

Edit

About these curly braces: these are attribute value templates (AVT). They are semantically equivalent in an XSLT transformation:

 <foo> <xsl:attribute name="bar"> <xsl:value-of select="XPathExpression"/> </xsl:attribute> </foo> <foo bar="{XPathExpression}"/> 

The second is just a shortcut to the first.

About variables and parameters: Syntactically there is no difference between a variable and a parameter; where you reference $foo in an XPath expression, it will work the same if foo is defined by xsl:variable or xsl:param .

The difference between them is how they are populated. Variables are populated in the xsl:variable declaration. Parameters are declared in the named template using xsl:param , but they are populated with any calls to the named template using xsl:with-param , for example:

 <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 exception to this are parameters that are a child of xsl:stylesheet . It is not possible to populate these parameters inside a transform they are filled from the outside, a transformation is called by some (environment-dependent) mechanism.

A fairly common use case is offset by the fact that XSLT does not have a system date function. So you will see something like:

 <xsl:stylesheet ... <xsl:param name="system-date"/> ... 

and then when calling the transform, something like this (in C #):

 XsltArgumentList args = new XsltArgumentList(); args.AddParam("system-date", "", DateTime.Now.ToString("s")); xslt.Transform(input, args, result); 
+4
source share

Try the following:

 <xsl:if test="not($var_myparam = 'no'))"> </xsl:if> 

The problem is how XPath calculates booleans. Any non-empty string will be evaluated as true in XPath. Make this entry about xpath booleans .

As for your other questions ... Variables and parameters act the same in XPath expressions. Both refer to the form of $ var.

For any XSLT attribute named "select" you do not need parentheses. Brackets are used in so-called "attribute value patterns". You use them when XSLT expects 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 specification talks about AVT , and therefore this page .

+3
source share

All Articles