I have a reasonably complex call to xsl:apply-templates:
<xsl:apply-templates select="columnval[@id
and not(@id='_Name_')
and not(@id='Group')
and not(@id='_Count_')]"/>
The expression is reused in other places like this:
<xsl:apply-templates select="someothernode[@id
and not(@id='_Name_')
and not(@id='Group')
and not(@id='_Count_')]"/>
I want to generalize it somehow, so I can define it once and reuse it elsewhere. However, this doesn't seem to work:
<xsl:variable name="x">@id and not(@id='_Name_') and not(@id='Group') and not(@id='_Count_')</xsl:variable>
<xsl:apply-templates select="columnval[$x]"/>
<xsl:apply-templates select="someothernode[$x]"/>
Is there a better / different way of doing this? All I want is to reuse the xpath expression in multiple different calls to xsl:apply-templates (some of which select from different children).
This is going to be used in a client application, so I can't use any extensions or switch to XSLT 2 unfortunately. :(
Thanks.
Refactoring @Robert Rossney and @Tomalak
With the extension exsl:nodeset, you can create a named template that accepts a nodeset $x and returns the filtered nodeset according to your static predicate.
You can also define a function, in XSLT 2.0.
How about:
You could make
$filter
a param, and pass it in from the outside for example.What you cannot do (as you've noticed) is use variables to store XPath expressions.
I would take a look at using an extension to xslt. I don't think you can do it in "standard" xslt.
This extension can do what you want: http://www.exslt.org/dyn/functions/evaluate/index.html
Both XSLT 1.0 and XSLT 2.0 do not support dynamic evaluation.
One way to do this is using
<xsl:function>
in XSLT 2.0 or<xsl:call-template>
in XSLT 1.0.then you could use this function:
Certainly, you could specify the test in specific match patterns as suggested by Robert Rossney, and this might be the best way.
In case you need to dynamically define which filtering function to use, one powerful tool is the FXSL library, which implements Higher-Order-Functions (HOF) in XSLT. HOF are functions that accept other functions as parameters and can return a function as their result.
Using this approach, you dynamically determine and pass to the
my:test()
as parameter a function that does the test.You can't construct XPath dynamically in XSLT (at least, not XSLT 1.0). But you can easily accomplish what you're trying to do using template modes: