1

我正在尝试基于变量创建动态行过滤器。我有以下代码:

<xsl:variable name="filter" select="contain(@Title, 'title1') or contain(@Title, 'title2')"/>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[string($filter)]" />

不幸的是,这似乎不起作用,我最终得到了所有行。我猜过滤器实际上并没有得到应用,因​​为我可以复制并粘贴 $filter 变量的输出,将其复制并粘贴到 Row[] 中,它可以按预期工作。

以前有人尝试过这样做吗?

如果您想知道过滤器变量实际上是使用拆分字符串的模板创建的:title1 - title2 - title3 并返回一个字符串,例如: contains(@Title, 'title1') 或 contains(@Title, 'title2' ) 或包含(@Title, 'title3')

任何帮助将不胜感激!

4

1 回答 1

3

你不能做你似乎在这里尝试的事情。XPath 表达式是原子的,您不能保存它的一部分并重新使用它们(除了它是contains(),不是contain())。

你需要这样的东西:

<xsl:variable name="Rows" select="
  /dsQueryResponse/Rows/Row[
    contains(@Title, 'title1') or contains(@Title, 'title2')
  ]
" />

你的“过滤器”不起作用,因为如果$filter是一个字符串,那么它就是一个字符串,没有别的。它并没有仅仅因为它看起来像 XPath 就具有神奇的意义。;-)

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[string($filter)]" />

计算为非空字符串作为谓词。并且任何非空字符串的计算结果都为 true,这使得表达式返回存在的每个节点。

如果您想要基于输入字符串的动态过滤器,请执行以下操作:

<xsl:variable name="filter" select="'|title1|title2|title3|'" />
<xsl:variable name="Rows" select="
  /dsQueryResponse/Rows/Row[
    contains(
      $filter,
      concat('|', @Title, '|')
    )
  ]
" />

如果您查找“title1”,使用分隔符还可以防止“title11”出现。

确保您的过滤器始终以分隔符开头和结尾,并使用不太可能作为@Title. (例如,您可以使用&#13;。如果您的标题不能是多行的,这是非常安全的。)

于 2009-12-09T21:30:53.160 回答