Я использую XSLT. Я знаю выражения встроенных функций Есть ли способ объявить именованную функцию в выражении xpath? потому что мне нужно имя функции для реализации рекурсивного вызова.
Как я могу реализовать определяемую пользователем функцию с именем в выражении 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)
Я думаю, учитывая последний разрешенный синтаксис.
$F := $f(?, $f)
великолепно! Однако это делает определение F()
нечитаемым -- читателю не очевидно, каковы типы аргументов F()
, и он должен изучить другие функции, чтобы понять, что это за типы... -- что-то, скорее, время трудоемки и подвержены ошибкам по сравнению с явным определением. Даже если мы разработаем инструмент, который будет генерировать полную сигнатуру F(), это все равно будет трудоемким и трудным для применения - другими словами, неудобно.
- person Dimitre Novatchev; 28.12.2019
var
для объявления переменных без их ввода, мои первоначальные мысли заключались в том, что мне это не нужно и я никогда не буду его использовать; но в настоящее время я считаю это весьма полезным, когда, например, использую Saxon в C # и копаюсь в его сложных API.
- person Martin Honnen; 28.12.2019
var
. Это подчеркивает названия типов и помогает читателю быстрее привыкнуть к новым типам.
- person Dimitre Novatchev; 29.12.2019
В XPath нельзя объявить именованную функцию; XPath 3.1 допускает только анонимные встроенные функции, и они не могут быть рекурсивными. Мне сказали, что есть способ добиться рекурсии в анонимных функциях, используя технику, называемую Y-комбинаторами, но это довольно ошеломляюще, и я никогда не думал об этом. Наилучший подход, как предлагает Мартин, состоит в том, чтобы поместить эту часть логики на уровень XSLT.
xsl:function
, вы можете сделать это легко, в чистом XPath используйтеlet
. - person Martin Honnen   schedule 27.12.2019