views:

765

answers:

1

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!

+2  A: 

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 &#13;. If your title cannot be multi-line this is pretty safe.)

Tomalak
So there is no way to create a truly dynamic filter? somewhat like you would do in php/asp?I like your delimiter idea though, for some reason when I used in my SP Designer it crashed and created 100lines worth of - If I tried to open the file in SP Designer, it would come up blank, yet the file size was 145kb.I was looking for a cleaner solution, but I guess I can't be too picky, right?
TeckniX
You realize that `` is ASCII CR? Just sayin'. ;) I don't really see how that would crash the whole thing. I usually edit my XSLT files in a normal text editor, I have no experience with SP Designer. The delimited string approach is the simplest way to create a truly dynamic filter. It is more or less what you intend, only in an XSLT/XPath compliant way.
Tomalak