Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to build a recursive navigation in XSL/XML
    primarykey
    data
    text
    <p>I'm trying to build a navigation that in theory could recurse infinitely with XSL. Unfortunately my skills in this arena are still being built. Can anyone tell me where I'm going wrong with this code?</p> <p>The kicker here is that the first 2 levels of the nav are somewhat unique (class names and such) but after level 3 the nav is pretty much the same elements being nested over and over.</p> <p><strong>To Update:</strong> There's no recursion after nav level 2, the output is non existent after level 2, and I can't figure out how to apply the recursion. I feel like this should be easier but my skills in XSL are not that great.</p> <p><strong>HTML (What we need it to produce):</strong></p> <pre><code> &lt;ul class="nav-l1"&gt; &lt;li class="nav-active"&gt;&lt;a href="nav2.html" class="nav-item trigger-chan nav-next"&gt;&lt;span&gt;&lt;span class="trigger-cntr"&gt;First Level Parent&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;ul class="nav-l2 nav-hidden"&gt; &lt;li class="nav-active"&gt;&lt;a href="nav2.html" class="nav-item"&gt;&lt;span&gt;Overview&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item trigger-chan nav-next"&gt;&lt;span&gt;&lt;span class="trigger-cntr"&gt;Second Level Parent&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;ul class="nav-ls nav-hidden"&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Third Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Third Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Second Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item trigger-chan nav-next"&gt;&lt;span&gt;&lt;span class="trigger-cntr"&gt;First Level Parent&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;!-- 2nd level of navigation. --&gt; &lt;ul class="nav-l2 nav-hidden"&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Overview&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item trigger-chan nav-next"&gt;&lt;span&gt;&lt;span class="trigger-cntr"&gt;Second Level Parent&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;!-- 3rd level of navigation. --&gt; &lt;ul class="nav-ls nav-hidden"&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Third Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Third Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Third Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Second Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" class="nav-item"&gt;&lt;span&gt;Second Level&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; </code></pre> <p><strong>Sample XML (The format of the initial data feed):</strong></p> <pre><code>&lt;data&gt; &lt;folders level="1"&gt; &lt;folder clickable="Y" url="/lorem/ipsum.html" name="Lorem Ipsum"/&gt; &lt;folder clickable="Y" url="/level/one.html" name="Level One"/&gt; &lt;folder clickable="Y" url="/foo/bar.html" name="Foo Bar"&gt; &lt;folders level="2"&gt; &lt;folder clickable="Y" url="/level/two.html" name="Level two"/&gt; &lt;folder clickable="Y" url="/child/item.html" name="Child Item"&gt; &lt;folders level="3"&gt; &lt;folder clickable="Y" url="/child/child/item.html" name="Child's Child Item"&gt; &lt;folders level="4"&gt; &lt;folder clickable="Y" url="/destiny/child/item.html" name="Destiny's Child"/&gt; &lt;/folders&gt; &lt;/folder&gt; &lt;/folders&gt; &lt;/folder&gt; &lt;/folders&gt; &lt;/folder&gt; &lt;/folders&gt; &lt;/data&gt; </code></pre> <p><strong>XSL (What we need to transform the XML):</strong></p> <pre><code> &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt; &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output method="html" omit-xml-declaration="yes" indent="yes"/&gt; &lt;xsl:template match="/"&gt; &lt;xsl:choose&gt; &lt;xsl:when test="/data/folders"&gt; &lt;!-- NAVIGATION BEGINS HERE --&gt; &lt;ul class="nav-l1"&gt; &lt;!-- LEVEL 1 --&gt; &lt;xsl:for-each select="/data/folders[@level=1]/folder[not (@clickable ) or @clickable ='Y' ]"&gt; &lt;li&gt; &lt;xsl:if test="@selected='Y'"&gt; &lt;xsl:attribute name="class"&gt;nav-active&lt;/xsl:attribute&gt; &lt;/xsl:if&gt; &lt;a href="{@url}" class="nav-item"&gt; &lt;xsl:choose&gt; &lt;xsl:when test="child::*"&gt; &lt;xsl:attribute name="class"&gt;trigger-chan nav-next&lt;/xsl:attribute&gt; &lt;span&gt; &lt;span class="trigger-cntr"&gt; &lt;xsl:value-of select="@name"/&gt; &lt;/span&gt; &lt;/span&gt; &lt;/xsl:when&gt; &lt;xsl:otherwise&gt; &lt;span&gt;&lt;xsl:value-of select="@name" /&gt;&lt;/span&gt; &lt;/xsl:otherwise&gt; &lt;/xsl:choose&gt; &lt;/a&gt; &lt;!-- LEVEL 2 --&gt; &lt;xsl:choose&gt; &lt;xsl:when test="child::*"&gt; &lt;ul class="nav-l2 nav-hidden"&gt; &lt;xsl:for-each select="folders[@level=2]/folder[not (@clickable ) or @clickable ='Y' ]"&gt; &lt;li&gt; &lt;xsl:if test="@selected='Y'"&gt; &lt;xsl:attribute name="class"&gt;nav-active&lt;/xsl:attribute&gt; &lt;/xsl:if&gt; &lt;a href="{@url}" class="nav-item"&gt; &lt;xsl:choose&gt; &lt;xsl:when test="child::*"&gt; &lt;xsl:attribute name="class"&gt;trigger-chan nav-next&lt;/xsl:attribute&gt; &lt;span&gt; &lt;span class="trigger-cntr"&gt; &lt;xsl:value-of select="@name"/&gt; &lt;/span&gt; &lt;/span&gt; &lt;/xsl:when&gt; &lt;xsl:otherwise&gt; &lt;span&gt;&lt;xsl:value-of select="@name" /&gt;&lt;/span&gt; &lt;/xsl:otherwise&gt; &lt;/xsl:choose&gt; &lt;/a&gt; &lt;!-- LEVEL 3 and beyond ... --&gt; &lt;xsl:apply-templates /&gt; &lt;/li&gt; &lt;/xsl:for-each&gt; &lt;/ul&gt; &lt;/xsl:when&gt; &lt;xsl:otherwise&gt; &lt;/xsl:otherwise&gt; &lt;/xsl:choose&gt; &lt;/li&gt; &lt;/xsl:for-each&gt; &lt;/ul&gt; &lt;/xsl:when&gt; &lt;/xsl:choose&gt; &lt;/xsl:template&gt; &lt;!-- Infinity and beyond (=&gt; Level 3) --&gt; &lt;xsl:template name="folder"&gt; &lt;ul class="nav-ls nav-hidden"&gt; &lt;li&gt; &lt;xsl:if test="@selected='Y'"&gt; &lt;xsl:attribute name="class"&gt;nav-active&lt;/xsl:attribute&gt; &lt;/xsl:if&gt; &lt;a href="{@url}" class="nav-item"&gt; &lt;xsl:choose&gt; &lt;xsl:when test="child::*"&gt; &lt;xsl:attribute name="class"&gt;trigger-chan nav-next&lt;/xsl:attribute&gt; &lt;span&gt; &lt;span class="trigger-cntr"&gt; &lt;xsl:value-of select="@name"/&gt; &lt;/span&gt; &lt;/span&gt; &lt;/xsl:when&gt; &lt;xsl:otherwise&gt; &lt;span&gt;&lt;xsl:value-of select="@name" /&gt;&lt;/span&gt; &lt;/xsl:otherwise&gt; &lt;/xsl:choose&gt; &lt;/a&gt; &lt;xsl:apply-templates select="folders[@level&gt;3]/folder" /&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p>Any help is greatly appreciated. </p> <p>Thanks!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload