如何在xpath表达式中使用名称实现用户定义的函数?

时间:2019-12-27 03:52:27

标签: xslt xpath xslt-3.0 xpath-3.1

我正在使用XSLT。我知道Inline Function Expressions,有什么方法可以在xpath表达式中声明命名函数吗?因为我需要函数名来实现递归调用。

2 个答案:

答案 0 :(得分:3)

在XSLT中,我只是建议使用xsl:function,因为这样您的函数就有了一个名称,您可以在函数主体内部递归调用它。

至于纯XPath 3,几年前Dimitre在https://dnovatchev.wordpress.com/2012/10/15/recursion-with-anonymous-inline-functions-in-xpath-3-0-2/中使用let和高阶函数(不幸的是,Saxon 9 HE中不支持该功能)探索了该路径,我认为他的代码在那里使用的函数类型语法与最终规范不太一致,因此他的示例必须是

let $f := 
    function($n as xs:integer,
             $f1 as function(xs:integer, function(*)) as xs:integer) as xs:integer {
        if ($n eq 0)
        then 1
        else $n * $f1($n -1, $f1)

    },
    $F := function($n as xs:integer) as xs:integer {
        $f($n, $f)
    }
return $F(5)

可以缩短为

let $f := 
    function($n as xs:integer,
             $f1 as function(xs:integer, function(*)) as xs:integer) as xs:integer {
        if ($n eq 0)
        then 1
        else $n * $f1($n -1, $f1)

    },
    $F := $f(?, $f)
return $F(5)

我认为给出了最新允许的语法。

答案 1 :(得分:1)

无法在XPath中声明命名函数; XPath 3.1仅允许匿名内联函数,并且这些函数不能递归。有人告诉我,有一种方法可以使用称为Y-combinators的技术来实现匿名函数的递归,但是这相当令人难以置信,而且我从来没有想过。正如Martin所建议的,最好的方法是将这部分逻辑放在XSLT级别。