How can I implement a user-defined function with a name in the xpath expression?

430 Views Asked by At

I am using XSLT. I know the Inline Function Expressions, Is there some way to declare a named function in xpath expression? because I need the function name to implement a recursive call.

2

There are 2 best solutions below

6
On BEST ANSWER

In XSLT I would simply suggest to use xsl:function as that way your function has a name and you can call it recursively inside of the function body.

As for pure XPath 3, Dimitre explored that path some years ago in https://dnovatchev.wordpress.com/2012/10/15/recursion-with-anonymous-inline-functions-in-xpath-3-0-2/ using let and higher-order functions (a feature not supported unfortunately in Saxon 9 HE), I think his code there uses a function type syntax not quite aligned with the final spec so his example would need to be

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)

which could be shortened to

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)

I think given the latest allowed syntax.

2
On

There is no way to declare a named function in XPath; XPath 3.1 only allows anonymous inline functions, and these cannot be recursive. I'm told that there's a way to achieve recursion in anonymous functions using a technique called Y-combinators, but it's fairly mind-boggling and I've never got my head around it. Your best approach, as Martin suggests, is to put this part of the logic at the XSLT level.