- From: Dimitre Novatchev <dnovatchev@gmail.com>
- Date: Sat, 29 Mar 2025 07:39:07 -0700
- To: Mukul Gandhi <gandhi.mukul@gmail.com>
- Cc: public-xslt-40@w3.org
- Message-ID: <CAK4KnZfNz4tmetADwV8Jk_sNCRXoGy61MzDc4jZ7dsNJQk=now@mail.gmail.com>
This issue is well known in XPath 3.
There is a way to use recursion with anonymous (inline) functions in pure
XPath 3, and I reported it in my blog and at the Balisage 2013 conference.
Since then, I have built my own, pure XPath 3.1 function libraries using
this technique.
Here is a simple example:
let $fact-base := 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)
},
$Fact := function($n as xs:integer) as xs:integer
{
$fact-base($n, $fact-base)
}
return
$Fact(5)
One can run it with BaseX or with Oxygen, or directly online with BaseX
Fiddle: https://fiddle.basex.org/.
Using the same technique, one can also implement *mutual recursion* in pure
XPath 3:
https://dnovatchev.wordpress.com/2023/10/04/mutual-recursion-with-anonymous-inline-functions-in-xpath-3/
Here is the original blog article from 2012:
https://dnovatchev.wordpress.com/2012/10/15/recursion-with-anonymous-inline-functions-in-xpath-3-0-2/
Here is the paper at Balisage 2013:
https://www.balisage.net/Proceedings/vol10/html/Novatchev01/BalisageVol10-Novatchev01.html
In Xpath 4 there will be more convenient and direct ways to implement
recursion, such as using *methods *of a map:
https://qt4cg.org/specifications/xquery-40/xpath-40.html#id-methods
Thanks,
Dimitre.
On Sat, Mar 29, 2025 at 1:29 AM Mukul Gandhi <gandhi.mukul@gmail.com> wrote:
> Hi XSLT community group,
> I 've following XSLT3 stylesheet:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> version="3.0">
>
> <xsl:output method="xml" indent="yes"/>
>
> <xsl:variable name="factorial" select="function($num) { if ($num eq
> 0) then 1 else ($num * $factorial($num - 1)) }"/>
>
> <xsl:template match="/">
> <result>
> <answer>
> <xsl:value-of select="$factorial(2)"/>
> </answer>
> <answer>
> <xsl:value-of select="$factorial(3)"/>
> </answer>
> <answer>
> <xsl:value-of select="$factorial(4)"/>
> </answer>
> </result>
> </xsl:template>
>
> </xsl:stylesheet>
>
> Within this stylesheet, value of the variable "factorial" is an XPath
> 3.1 inline function definition that uses recursion. I think, that this
> stylsheet when run should produce an XSL transformation result as
> follows:
>
> <?xml version="1.0" encoding="UTF-8"?><result>
> <answer>2</answer>
> <answer>6</answer>
> <answer>24</answer>
> </result>
>
> Saxon-HE 12.4 has issues running this stylesheet, and produces
> following XSL transformation result:
>
> Variable $factorial cannot be used within its own declaration
>
> Please take appropriate measures to solve an XSL transformation issue
> mentioned within this mail. I'm not sure, but probably an XSLT3 test
> case corresponding to this use case should be added to XSLT3 test
> suite.
>
>
> --
> Regards,
> Mukul Gandhi
>
>
Received on Saturday, 29 March 2025 14:39:23 UTC