XSLT Recursion07 January 2013
XSLT Recursion, should be considered one of your best friends when working with XSLT. Recursion should be your best friend in any language you program, as it gives your code a certain level of elegance and simplicity. Bottom line is you're stuck implementing something in XSLT, such as trying a Loop in XSLT and you got stuck your search led you to Recursion and you ended up here to learn more.
First of all what is Recursion?
Recursion or in this case XSLT Recursion, is a particular type of function that calls itself as many times as required to find the final solution. The most basic use-case is calculating the value of factorial numbers. Where a function calls itself to multiply the current number to the result of the same function -1. An Introduction to Recursion is provided in this article.
Is XSLT Recursion different from recursion in other languages?
Not really, XSLT Recursion works in the same way as other languages, the difference is that XSLT is a functional language, it does not support standard for-to loops so XSLT Recursion should really be one of your strengths to allow you to loop over items. The other difference is that in other language usually you have recursive functions, in xslt you have recursive templates. Right xslt templates calling themselves over and over, in a recursive manner.
Where would XSLT Recursion be useful
There are plenty of times where XSLT Recursion can really make your life simple, I'll take a simple use-case. Below find some XML have a look at it.
<root> <navigation> <page id='1'>Home</page> <page id='2'>About</page> <page id='3' parent='2'>Staff</page> <page id='4'>Contact</page> <page id='5'>Terms & Conditions</page> <page id='6' parent='3'>John Doe</page> <page id='7' parent='3'>Directors</page> </navigation> </root>
So there you have an XML representing some pages from a web-page, which has hierarchical properties described in the
parent attribute. The system does not define a limit of sub-pages allowed so it is safe to assume that there could be more then three levels. What would you do if you had to transform this to basic breadcrumbs using XSLT without Recursion? Most likely do a three level-check to add the next level. Lets see how a Recursive XSLT template would look like.
<xsl:template name='breadcrumb'> <xsl:with-param name='pageid'> <!-- Define a variable to select the current page --> <xsl:variable name='currentPage' select='/root/navigation/page[@id=$pageid]'/> <xsl:if test='$currentPage/@parent' <!-- If this page has a parent do a recursive call using the parent id --> <xsl:call-template name='breadcrumb'> <xsl:with-param name='pageid' select='$currentPage/@parent'> </xsl:call-template> <xsl:text> / </xsl:text> </xsl:if> <xsl:value-of select='$currentPage'> </xsl:template>
The above XSLT Recursion example explains how to transform the XML into a breadcrumb output for the current page. Note that in real breadcrumbs you would also have links which were omitted for the simplicity of the example.
How do I build my own Recursive XSLT template
Easy, think of the basics and keep it simple the rule is to delegate where possible. In our case the Recursive template needed to ask two questions, What to do when the current page has no parent, and when a page has the parent. The base case was that if our XSLT Recursive template had no parents for the current page, it should output the Name of the page. Secondly if it has a parent, it should first ask the parent to print itself and its predecessors, thus making an XSLT recursive call.
I hope that this XSLT Recursion Guide was useful and easy to understand; should you have any question in relation to XSLT Recursion or any other related topics feel free to drop a comment on this post and I will gladly answer your question.