I'm trying to create a dynamic row filter based on a variable. I have the following code:
<xsl:variable name="filter" select="contain(@Title, 'title1') or contain(@Title, 'title2')"/>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[string($filter)]" />
This unfortunately doesn't seem to work and I end up with all rows. I'm guessing the filter doesn't actually get applied, since I can copy and paste the output of the $filter variable, copy and paste it in the Row[] and it works as expected.
Anyone tried to do this before?
In case you're wondering the filter variable is actually created using a template that splits a string like: title1 - title2 - title3 and returns a string like: contain(@Title, 'title1') or contain(@Title, 'title2') or contain(@Title, 'title3')
Any help would be greatly appreciated!
You can't do what you seem to be attempting here. An XPath expression is atomical, you can't save parts of it and re-use them (apart from that it is contains()
, not contain()
).
You need something like this:
<xsl:variable name="Rows" select="
/dsQueryResponse/Rows/Row[
contains(@Title, 'title1') or contains(@Title, 'title2')
]
" />
Your "filter" does not work because if $filter
is a string, then it is a string, nothing else. It does not get a magical meaning just because it looks like XPath. ;-)
This
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[string($filter)]" />
evaluates to a non-empty string as the predicate. And any non-empty string evaluates to true, which makes the expression return every node there is.
If you want a dynamic filter based on an input string, then do this:
<xsl:variable name="filter" select="'|title1|title2|title3|'" />
<xsl:variable name="Rows" select="
/dsQueryResponse/Rows/Row[
contains(
$filter,
concat('|', @Title, '|')
)
]
" />
The use of delimiters also prevents "title11" from showing up if you look for "title1".
Make sure your filter always starts and ends with a delimiter, and use a delimiter that is reasonably unlikely to ever occur as a natural part of @Title
. (For example, you could use
. If your title cannot be multi-line this is pretty safe.)