I love XSL!
I have been fighting with recursion for ages now and have found it to always be a real problem effecting performance, quite often you have to use complicated caching techniques, until now!
Using XSL you can perform recursion techniques on flat XML data. It sounds complicated but really it isn’t.
Say you have node data like the following (in a flat structure).
<tree>
<node icon=”" id=”1″ objectID=”9″ parentID=”0″ recordID=”15″ ref=”sites” title=”Sites”/>
<node icon=”" id=”2″ objectID=”9″ parentID=”0″ recordID=”28″ ref=”media” title=”Template Media”/>
<node icon=”" id=”3″ objectID=”9″ parentID=”0″ recordID=”31″ ref=”templates” title=”Templates”/>
<node icon=”site.png” id=”4″ objectID=”11″ parentID=”1″ recordID=”1″ ref=”refresh–test” title=”Refresh”/>
<node icon=”page.png” id=”5″ objectID=”1″ parentID=”4″ recordID=”134″ ref=”home” title=”Home”/>
<node icon=”form.png” id=”6″ objectID=”12″ parentID=”5″ recordID=”60″ ref=”enq_form” title=”Enquiry Form”/>
<node icon=”form.png” id=”7″ objectID=”12″ parentID=”5″ recordID=”61″ ref=”site_review” title=”Site Review”/>
<node icon=”menu.png” id=”11″ objectID=”5″ parentID=”4″ recordID=”8″ ref=”topnav” title=”Top Nav 2″/>
<node icon=”" id=”12″ objectID=”9″ parentID=”0″ recordID=”33″ ref=”users” title=”Users”/>
</tree>
Using XSL you can build a hierarchical tree from this data:
<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform“
version=”1.0″> <xsl:template match="tree">
<!-- Starts the tree -->
<ol>
<xsl:apply-templates/>
</ol>
</xsl:template>
<!-- Selects root nodes -->
<xsl:template match=”//node[@parentID=0]“> <xsl:call-template name="process-branch">
<xsl:with-param name=”id”><xsl:value-of select=”@id”/></xsl:with-param>
<xsl:with-param name=”parentID”><xsl:value-of
select=”@parentID”/></xsl:with-param>
</xsl:call-template> </xsl:template> <!-- Recursive function -->
<xsl:template name=”process-branch”>
<xsl:param name=”id”/>
<xsl:param name=”parentID”/> <xsl:choose>
<!– If element has no sub-nodes –>
<xsl:when test=”count(//node[@parentID=current()/@id])=0″>
<!– Writes the node –>
<li>
<a href=”" mce_href=”"><xsl:value-of select=”@title” /></a>
</li>
</xsl:when>
<!– If element has sub-nodes–>
<xsl:otherwise>
<!– Starts a node with children element –>
<li>
<a href=”" mce_href=”"><xsl:value-of select=”@title” /></a>
<ol>
<!– For every sub-nodes of current node –>
<xsl:for-each select=”//node[@parentID=current()/@id]“>
<!– Recurse the branch processing –>
<xsl:call-template name=”process-branch”>
<xsl:with-param name=”id”><xsl:value-of
select=”@id”/></xsl:with-param>
<xsl:with-param name=”parentID”><xsl:value-of
select=”@parentID”/></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</ol>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Obviously you can replace the html with whatever elements you wish, even build hierarchical XML.
You then use the (rather handy) coldfusion function
#XMLTransform(XMLParse(xmldata), xslSheet)#
And there you have it, no long loops with recurring queries!