用变量/函数替换XPath表达式

时间:2015-01-05 19:59:41

标签: xslt xpath xslt-2.0

我有一个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">

有没有办法用我想要分组的函数和节点定义变量,然后在group-by表达式中使用该变量?或其他一些方法来做到这一点?我尝试使用一个简单的变量,但这两个都不起作用(第二个是单引号):

<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"/>

谢谢!

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

你问题的简短回答是否定的。变量保存评估表达式的结果,而不是表达式本身。此外,您无法在参数中传递表达式 - 您只传递字符串

虽然你可以在某种程度上围绕这个问题跳舞,如Martin Honnen在他的回答中所示,你应该确定你的处理器是否支持某种evaluate()扩展函数,例如:http://www.saxonica.com/documentation/#!functions/saxon/evaluate

答案 2 :(得分:0)

这里真正需要的是更高阶函数:如果变量$ f绑定到计算分组键的函数,那么你可以执行group-by =&#34; $ f(。)&#34; 。这需要XSLT 3.0。但是,它可以使用Dimitre Novatchev的FXSL库在XSLT 2.0中进行模拟。我还没有将它与Saxon-CE一起使用,但除了它可能有点大之外,原则上没有理由说它为什么不能工作。