Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 如何使用xpath表达式中的名称实现用户定义的函数?_Xslt_Xpath_Xslt 3.0_Xpath 3.1 - Fatal编程技术网

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

Xslt 如何使用xpath表达式中的名称实现用户定义的函数?,xslt,xpath,xslt-3.0,xpath-3.1,Xslt,Xpath,Xslt 3.0,Xpath 3.1,我正在使用XSLT。我知道,有没有办法在xpath表达式中声明命名函数?因为我需要函数名来实现递归调用。在XSLT中,我只建议使用xsl:function,因为这样您的函数就有了一个名称,并且可以在函数体内部递归调用它 至于纯XPath 3,Dimitre几年前在使用let和高阶函数(Saxon 9 HE中不幸不支持这一特性)时探索了这一途径,我认为他的代码使用的函数类型语法与最终规范不太一致,因此他的示例需要 let $f := function($n as xs:integer,

我正在使用XSLT。我知道,有没有办法在xpath表达式中声明命名函数?因为我需要函数名来实现递归调用。

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

至于纯XPath 3,Dimitre几年前在使用
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)

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

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

使用XSLT和
xsl:function
您可以很容易地做到这一点,在纯XPath中使用
let
。在纯XPath中如何做到这一点?你想给我看一个代码片段吗?@cmf41013这里有一个最近的例子:@cmf41013最近的例子见这个答案:Martin,
$F:=$F(?,$F)
这个表达式太棒了!然而,这使得
F()
的定义不可读——读者不清楚
F()
的参数类型是什么,他必须研究其他函数才能理解这些类型……——与显式定义相比,它相当耗时且容易出错。即使我们设计了一个工具来生成F()的完整签名,这仍然是耗时且难以实施的——换句话说,是不方便的。@DimitreNovatchev,我明白你的意思,但我只是想提供最新XPath版本提供的一个选项,我不想让这种方式优于我引用的代码。一般来说,我认为这取决于视角,例如在C#中,当他们引入
var
来声明变量而不键入变量时,我最初的想法是我不需要它,也永远不会使用它;但是现在我认为在C语言中使用撒克逊并通过它的复杂API来挖掘它是一个很大的帮助。@ DimitreNovatchev,XPath中的占位符语法当然可以减少当你将XQuery模块导入XSLT并尝试使用它时必须编写的代码。是的,但是我正在编写函数库,其中每个函数都必须有一个定义良好的签名——否则我们如何才能向目标受众解释函数采用的参数类型及其含义?另一方面,“内部”或“工作者”函数旨在保持不可见——也就是说,应该隐藏已发布函数的实际实现。Re:“这相当令人难以置信,我从来没有想过它。”。。。引用@martin_honnen在上面的评论:“用纯XPath,你可以很容易地做到这一点”:)你们谈论的是同一件事吗?当我试图理解Y combinator时,我肯定发现它令人难以置信;我发现Dimitre的方法非常简单,而且从来没有完全理解为什么一个容易遵循,而另一个不容易。(所以:我认为MK和MH谈论的是同一件事,但我可能错了。)