Replacing XPath Expression with Variable/Function

2019-08-07 11:48发布

I have an XSLT 2.0 stylesheet. I need to perform a for-each-group loop, but the value I am grouping on may change, based on parameters passed into the stylesheet.

For example, if my XML looks like this (simplified for this example):

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

I want to perform a for-each-group, grouping on a function applied to the date node. for example, it might be this:

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

or this:

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

I might even need to group on a different node, like . So I could use:

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

Is there any way to define a variable with the function and node I want to group on and then use that variable in the group-by expression? or some other way to do this? I tried using a simple variable, but that did not work, both (the second is inside single quotes):

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

and

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

I have a related question, but it likely has the same answer. I also need to perform an where the select will also need to use this same variable, like:

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

Thanks!

3条回答
一夜七次
2楼-- · 2019-08-07 12:22

The real need here is for higher order functions: if the variable $f is bound to a function that computes the grouping key, then you can do group-by="$f(.)". This needs XSLT 3.0. However, it can be simulated in XSLT 2.0 using Dimitre Novatchev's FXSL library. I haven't used this with Saxon-CE, but apart from the fact that it's probably a bit big, there's no reason in principle why it shouldn't work.

查看更多
可以哭但决不认输i
3楼-- · 2019-08-07 12:31

You can use substring(*[local-name() = $var1], 1, $var2) where you then bind var1 as 'date' and the other variable with a number value.

查看更多
Rolldiameter
4楼-- · 2019-08-07 12:44

The short answer to your question is no. A variable holds the result of evaluating an expression, not the expression itself. Moreover, you cannot pass an expression as such in parameter - you are only passing a string.

While you can dance around the issue to some extent as shown by Martin Honnen in his answer, you should really find out if your processor supports some kind of evaluate() extension function, such as: http://www.saxonica.com/documentation/#!functions/saxon/evaluate for example.

查看更多
登录 后发表回答