Как я могу реализовать пользовательскую функцию с именем в выражении xpath?

Я использую XSLT. Я знаю встроенные выражения функций. Есть ли способ объявить именованную функцию в выражении xpath? потому что мне нужно имя функции для реализации рекурсивного вызова.

2 ответа

Решение

В XSLT я бы просто предложил использовать xsl:function так у вашей функции есть имя, и вы можете вызывать ее рекурсивно внутри тела функции.

Что касается чистого XPath 3, Димитр исследовал этот путь несколько лет назад в 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)

Я думаю, учитывая последний разрешенный синтаксис.

В XPath невозможно объявить именованную функцию; XPath 3.1 допускает только анонимные встроенные функции, и они не могут быть рекурсивными. Мне сказали, что есть способ добиться рекурсии в анонимных функциях, используя технику, называемую Y-комбинаторами, но это довольно ошеломляюще, и я никогда не думал об этом. Ваш лучший подход, как предлагает Мартин, - поместить эту часть логики на уровень XSLT.

Другие вопросы по тегам