BizTalk Utilities CV ,   Jobs ,   Code library
 
Home Page


Add/Edit your code items
Search the code library
Browse for the code library


XSLT
Re: DVC Algorithms in XSLT
trig functions in xslt
XSLT string Replace function
A Slide-In Menu made with XML/XSLT
What is SVG?
Family Tree maker
Alternative Ordering - ""Women and Children to the lifeboats first""
Restructuring flat delimited XML
Hex and Binary Conversions in XSLT - with Boolean math functions
Using XSLT to produce SVG (1)
Using XSLT to produce SVG (2)
Performance Tuning XSLT - Part 1
Performance Tuning XSLT - Part 2
Performance Tuning XSLT - Part 3
Performance Tuning XSLT - Part 4
Using XSLT to produce SVG (3)
XPath as parameters
Table with more than one column
Create an N-Column Table from XML node-set
Finding ""the corresponding node"" in a parallel subtree


 
 

<< XQuery.NET and XML >>


By Slawomir Tyszko
First Posted 01/06/2002
Times viewed 285

Another way of avoiding XSLT processor crash


This post contains attachments
v20020106162513.zip 

Summary An alternative solution to Dimitre Novatchev's way of avoiding XSLT processor crash due to deep recursive processing. This solution does not relinquish recursion, but drastically reduces its depth by using two named recursive templates instead of just one.

The way of avoiding XSLT processor crash presented in Dimitre Novatchev's snippet (posted 24 March 2001) is very interesting, but it can be used only in the simplest case - when recursion is used just to count the number of iterations, and there is no passing of data computed in a given step on to the following steps. Only in such simple cases you can give up recursion completely and adopt the solution based on a for-each loop, provided you'll be able to find a node-set containing a very large number of nodes.

But there are situations when you can't give up recursion, while you still want to avoid XSLT processor crash due to excessive recursion depth.
Take, for instance, the template named total-sales-value from chapter 8 (9 in the second edition) of the Michael Kay's XSLT Programmer's Reference. This recursive template calculates the total sales value of books specified by the list parameter as sum of the sales*price products for all book elements contained in the input node-set.
In a case like this you can't replace recursion with a for-each loop.

Luckily there is another, quite effective, way of avoiding the crash, without relinquishing recursion, consisting in drastically reducing recursion depth.
Suppose you've got 10000 items for which you want to compute sum of 10000 sales*price products by way of recursion, which considerably exceeds the depth of recursion allowed by your processor. In such a case you can partition that node-set into e.g. 100 chunks, each chunk containing 100 nodes, and use two recursive templates instead of just one. The template A would recursively compute the sum inside chunks, while template B would recursively call template A in order to process successive chunks. The combined maximum depth of recursion will be only 200 (100+100) instead of 10000 (100*100). Assuming that all XSLT processors allow recursion depth of at least 1000, this method allows you to safely carry out processing that would otherwise require recursion depth of 250000 (500*500).
Conceptually this is very simple, something similar to nested for loops in a typical procedural programming language.

I assembled this snippet by adding a second recursive template named total-total to the Michael Kay's example.
The total-total template is very similar to the Michael Kay's one. Apart from the main list parameter (input node-set) it has the chunk-size parameter allowing the user to specify the size of fragments (chunks) into which the input node-set will be divided. It first checks if the input node-set (list) is empty. If it is, it just returns 0 and quits. If not, it makes three things. First, it calls the total-sales-value template passing it the first chunk of nodes from the input node-set and storing the resulting partial value in the first-chunk variable. Next, the template calls itself recursively with the list parameter taking the remaining nodes (input node-set minus first chunk), and stores the result in the total-of-rest variable. Finally, it returns $first-chunk + $total-of-rest.

I tested this snippet with an XML file containing 10000 book elements, which I generated by replicating 5000 times the two elements from the original Michael Kay's example, and chunk-size parameter set to 100. Xalan, as well as XT, swallowed this file without any problems (it took Xalan 35 sec, while XT only 15 sec on a PC with 500 MHZ processor), while with conventional single-template solution XT couldn't cope with 2000-element file, reporting stack overflow.
Here I attach a reduced version with 100-element input file and chunk-size set to 10.
Important: If you would like to test the speed with 10000-element file, do not forget to change this parameter to 100.

 

Additional information


Rate this article on a scale of 1 to 10 (0 votes, average 0)

Your vote :  

<< XQuery.NET and XML >>





Leave a comment for this article
Your name
Your email (optional)
Your comment
Optional: Upload an attachment
Enter the code shown:

 
 

    Email TopXML