Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9018659
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T04:35:05+00:00 2026-06-16T04:35:05+00:00

I am trying to write a tail-recursive function in XSLT 2.0, which iterates through

  • 0

I am trying to write a tail-recursive function in XSLT 2.0, which iterates through a multivalued variable of dates and returns the earliest one. For some reason my function is not recognized by SaxonHE9.4 as tail-recursive and I get the following error, when the input file has more than 150-200 entries or so:

Error on line 73 of tail_rec_test.xsl: Too many nested function
calls. May be due to infinite recursion. in built-in template rule

Here’s my xml-input:

<?xml version="1.0"?>
<Events>
  <Event>
    <Date>2004-01-01</Date>
  </Event>
  <Event>
    <Date>2003-01-01</Date>
  </Event>
  <Event>
    <Date>2002-01-01</Date>
  </Event>
  <Event>
    <Date>2001-01-01</Date>
  </Event>
  <Event>
    <Date>2005-01-01</Date>
  </Event>
  <Event>
    <Date>2006-01-01</Date>
  </Event>
  <Event>
    <Date>2007-01-01</Date>
  </Event>
  <Event>
    <Date>2008-01-01</Date>
  </Event>
</Events>

This is what my xsl-file looks like:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:own="http://ownfunctions">
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/>


    <xsl:function name="own:findEarliestDate">
        <xsl:param name="dates" as="xs:date*"/>

        <xsl:variable name="size"><xsl:value-of select="count($dates)" /></xsl:variable>
        <xsl:choose>
            <xsl:when test="$size &gt; 0">
                <xsl:value-of select="own:findEarliestDate-helper($dates, $size, xs:date('2050-01-01'))" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="''"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>


    <xsl:function name="own:findEarliestDate-helper" as="xs:date">
        <xsl:param name="items" as="xs:date*"/>
        <xsl:param name="i" as="xs:integer"/>
        <xsl:param name="curMin" as="xs:date"/>

        <xsl:choose>
            <xsl:when
                test="$i = 0">
                <xsl:value-of select="xs:date($curMin)"/>           
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="item" as="xs:date">
                    <xsl:value-of select="xs:date($items[$i])"/>
                </xsl:variable>

                <xsl:variable name="next" as="xs:date">
                    <xsl:choose>
                        <xsl:when test="$item &lt; $curMin">
                            <xsl:value-of select="$item"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$curMin"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>

                <xsl:value-of select="own:findEarliestDate-helper($items, $i - 1, $next)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>


    <xsl:template match="Events">
        <xsl:variable name="items" as="xs:date*">
            <xsl:for-each select="Event">
                <xsl:value-of select="xs:date(Date)"/>
            </xsl:for-each>
        </xsl:variable>

        <Test>
            <EarliestDate>
                <xsl:value-of select="own:findEarliestDate($items)"/>
            </EarliestDate>
        </Test>
    </xsl:template>

</xsl:stylesheet>

How can I transform it into a correct tail-recursive function?
I have tested this example, but I cannot apply it to my own code:
http://www.nesterovsky-bros.com/weblog/2008/02/20/EfficientXslt20RecursionInSaxon9.aspx

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T04:35:06+00:00Added an answer on June 16, 2026 at 4:35 am

    I can’t repro this.

    Using Saxon 9.4.06EE (evaluation copy) the result is:

    <Test xmlns:fo="http://www.w3.org/1999/XSL/Format"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          xmlns:fn="http://www.w3.org/2005/xpath-functions"
          xmlns:own="http://ownfunctions">
       <EarliestDate>2001-01-01</EarliestDate>
    </Test>
    
    Saxon-EE 9.4.0.6J from Saxonica
    Java version 1.6.0_31
    Using license serial number XXXXXXXX
    Generating byte code...
    Stylesheet compilation time: 2168 milliseconds
    Processing file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml
    Using parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
    Building tree for file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml using class net.sf.saxon.tree.tiny.TinyBuilder
    Tree built in 10 milliseconds
    Tree size: 27 nodes, 80 characters, 0 attributes
    Execution time: 122ms
    Memory used: 52169472
    NamePool contents: 8 entries in 8 chains. 6 URIs
    

    BTW, one can use just this to produce the same result:

    <xsl:value-of select="min(/*/*/Date/xs:date(.))"/>
    

    Update:

    The problem is in this line:

                <xsl:value-of select="own:findEarliestDate-helper($items, $i - 1, $next)"/>
    

    Because the return type of the function is xs:date, the above line isn’t the last line in the execution sequence of the function. It produces a string (more precisely, a text node), and the XSLT processor needs to get this string and to convert it to an xs:date — that means that the memory ocupied by the function isn’t discarded and the call-stack continues to grow, until it overflows.

    The solution is simple:

    Replace the above with:

                <xsl:sequence select="own:findEarliestDate-helper($items, $i - 1, $next)"/>
    

    This produces an xs:date and the XSLT processor now recognizes the function as tail recursive.

    I tested the corrected code with 1000 events (on which the original code crashes) and the result is produced normally (and faster).

    Saxon-EE 9.4.0.6J from Saxonica
    Java version 1.6.0_31
    Using license serial number XXXXXXXXXX
    Generating byte code...
    Stylesheet compilation time: 2002 milliseconds
    Processing file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml
    Using parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
    Building tree for file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml using class net.sf.saxon.tree.tiny.TinyBuilder
    Tree built in 124 milliseconds
    Tree size: 3032 nodes, 9800 characters, 0 attributes
    Execution time: 364ms
    Memory used: 55089048
    NamePool contents: 8 entries in 8 chains. 6 URIs
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to write a tail-recursive function poly that will compute the value
I've had problem when trying write a function which has a default value when
I'm trying to write a function that sums integers, each of which are represented
I am trying to write a Tail Recursive procedure to count the number of
I'm trying to write a scala function which will recursively sum the values in
I'm trying to write a string processing function in F#, which looks like this:
I am trying to write two separate tail recursive functions that compute the length
I am trying write a function that generates simulated data but if the simulated
Trying to write a function to see how often an object exists and give
I am trying to write a program that will search through a main directories

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.