Project

Profile

Help

Allow for more nested template or function calls

Added by Marijn Sanderse about 6 years ago

I have a template that uses recursion to de-escape escaped xml to a serialized representation of the xml structure. The recursion runs quite deep, so deep that Saxon throws me an exception: net.sf.saxon.trans.XPathException: Too many nested template or function calls. The stylesheet may be looping. at error/etc/mailbase_starter_html.xsl line 499

I am pretty sure the stylesheet is not looping because the exact same stylesheet completes nicely on the same test case in Saxon 8.9.0.4 so I assume Saxon 9.8 is quicker in assuming the stylesheet is looping (or something like that).

Is there a way to instruct Saxon to allow for a higher number of recursive template calls?

SAXON-EE 9.8.0.12J / java 1.8.0_121


Replies (1)

RE: Allow for more nested template or function calls - Added by Michael Kay about 6 years ago

Saxon reports this error in response to a StackOverflow exception coming from Java. You can increase the permitted recursion depth by configuring the Java stack size, but there's nothing you can do about it at the Saxon level.

If it works in 8.9 and not in 9.8 that suggests we're using more stack space, which is a little unfortunate, but these things happen. I don't remember exactly what's changed that might cause this, but new functionality comes along from time to time, like tunnel parameters, that means the internals have to change.

If you hit this kind of problem there are several solutions:

(a) rewrite the code so it isn't recursive. The problem you describe can probably be tacked these days using xsl:analyze-string.

(b) make sure it's tail-recursive, so the recursive call is the last thing that happens, in which case Saxon re-uses the same stack frame for the recursive call

(c) instead of head-tail recursion, where the recursion depth is O(n), use divide-and-conquer recursion, where the maximum depth is O(log n). That typically means splitting a string into two and processing each half separately. Divide and conquer is also better for parallelism if that's ever needed.

    (1-1/1)

    Please register to reply