用 Variable/Function 替换 XPath 表达式

Replacing XPath Expression with Variable/Function

我有一个 XSLT 2.0 样式表。我需要执行一个 for-each-group 循环,但我分组的值可能会根据传递到样式表中的参数而改变。

例如,如果我的 XML 看起来像这样(针对此示例进行了简化):

<root><row><date>2001-01-01</date><text>abc</text></row><row><date>2003-04-02</date><text>xyz</text></row>...</root>

我想执行一个for-each-group,对应用于日期节点的函数进行分组。例如,它可能是这样的:

<xsl:for-each-group select="/root/row" group-by="substring(date,1,4)">

或者这个:

<xsl:for-each-group select="/root/row" group-by="substring(date,1,7)">

我什至可能需要在不同的节点上分组,比如 .所以我可以使用:

<xsl:for-each-group select="/root/row" group-by="$variable">

有没有什么方法可以用我想要分组的函数和节点定义一个变量,然后在分组依据表达式中使用该变量?或者其他一些方法来做到这一点?我尝试使用一个简单的变量,但没有用(第二个在单引号内):

<xsl:variable name="variable" select="substring(date,1,4)"/>

<xsl:variable name="variable" select="'substring(date,1,4)'"/>

我有一个相关的问题,但它可能有相同的答案。我还需要执行一个 select 也需要使用相同变量的位置,例如:

<xsl:value-of select="/root/row/$variable"/>

谢谢!

您可以使用 substring(*[local-name() = $var1], 1, $var2),然后将 var1 绑定为 'date' 并将另一个变量绑定为数值。

对您的问题的简短回答是否定的。变量保存表达式计算的结果,而不是表达式本身。此外,您不能在参数中传递 expression 本身 - 您只是传递 string

虽然您可以在某种程度上绕过这个问题,正如 Martin Honnen 在他的回答中所展示的那样,但您确实应该查明您的处理器是否支持某种 evaluate() 扩展函数,例如:http://www.saxonica.com/documentation/#!functions/saxon/evaluate例如。

这里真正需要的是高阶函数:如果变量 $f 绑定到计算分组键的函数,那么您可以执行 group-by="$f(.)"。这需要 XSLT 3.0。但是,可以使用 Dimitre Novatchev 的 FXSL 库在 XSLT 2.0 中对其进行模拟。我没有在 Saxon-CE 上使用过它,但除了它可能有点大这一事实之外,原则上没有理由不让它工作。