title: how to traverse xml file based on variables with XSL
body: <p>I recently asked a question on which engine to parse my xml and decided to stick to XSL, but I can only get the job half done. (ref: <a href="https://stackoverflow.com/questions/4891692/which-language-to-use-to-parse-xml-for-navigation">Which language to use to parse xml for navigation</a>)</p>
  
  <p>I've managed to get as far as traversing down <code>&lt;root&gt; --&gt; &lt;menu&gt; --&gt; &lt;nav&gt;</code> but any children under nav and my logic gets totally screwed up. </p>
  
  <p>Question is how do I repeat my logic in xsl to go deeper in the xml child nodes, when the @path is the next child node tier?</p>
  
  <p>Am I even doing this right? I feel like I'm missing something here and should be using templates somehow?</p>
  
  <p>For example here is my xsl style sheet.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!--
      Document   : sitemap.xsl
      Created on : 2 February 2011, 14:53
      Author     : Jared
      Description:
          Purpose of transformation follows.
  --&gt;
  &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
      &lt;xsl:output method="html" /&gt;
      &lt;xsl:param name="page" select="default"/&gt;
  
      &lt;xsl:template match="root"&gt;
          &lt;ul class="level-0 top-level"&gt;
              &lt;xsl:for-each select="*/nav"&gt;
                  &lt;xsl:choose&gt;
                      &lt;xsl:when test="$page = '/index.aspx'"&gt;
                          &lt;!-- level 0 --&gt;
                          &lt;li&gt;
                              &lt;a&gt;&lt;xsl:attribute name="href"&gt;&lt;xsl:value-of select="@path" /&gt;&lt;/xsl:attribute&gt;&lt;xsl:value-of select="@name" /&gt;&lt;/a&gt;
                          &lt;/li&gt;
                      &lt;/xsl:when&gt;
  
                      &lt;xsl:when test="@path=$page and $page != '/index.aspx'"&gt;
                          &lt;!-- level 2 --&gt;
                          &lt;li class="children-open current-menu-page"&gt;
                              &lt;a&gt;&lt;xsl:attribute name="href"&gt;&lt;xsl:value-of select="@path" /&gt;&lt;/xsl:attribute&gt;&lt;xsl:value-of select="@name" /&gt;&lt;/a&gt;
                              &lt;ul class="level-2 current-menu"&gt;
                                  &lt;xsl:for-each select="/root/menu/nav[@path=$page]/child::*"&gt;
                                      &lt;li&gt;
                                          &lt;a&gt;&lt;xsl:attribute name="href"&gt;&lt;xsl:value-of select="@path" /&gt;&lt;/xsl:attribute&gt;&lt;xsl:value-of select="@name" /&gt;&lt;br /&gt;&lt;/a&gt;
                                      &lt;/li&gt;
                                  &lt;/xsl:for-each&gt;
                              &lt;/ul&gt;
                          &lt;/li&gt;
                      &lt;/xsl:when&gt;
  
  
                      &lt;xsl:otherwise&gt;
                          &lt;li&gt;
                              &lt;a&gt;&lt;xsl:attribute name="href"&gt;&lt;xsl:value-of select="@path" /&gt;&lt;/xsl:attribute&gt;&lt;xsl:value-of select="@name" /&gt;&lt;/a&gt;
                          &lt;/li&gt;
                      &lt;/xsl:otherwise&gt;
  
  
                  &lt;/xsl:choose&gt;
  
              &lt;/xsl:for-each&gt;
  
          &lt;/ul&gt;
      &lt;/xsl:template&gt;
  
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>XML file looks something like this:</p>
  
  <pre><code>&lt;root name="menutest"&gt;
    &lt;menu&gt;
        &lt;nav name="home" path="index.php" /&gt;
  
        &lt;nav name="menulink1" path="link1.php"&gt;
            &lt;nav name="menulink1child1" path="menulink1childlink1.php"&gt;
               &lt;nav name="menulink1child1child1"
                    path="menulink1childlink1childlink1.php" /&gt;
            &lt;/nav&gt;
        &lt;/nav&gt;
  
        &lt;nav name="menulink2" path="link2.php"&gt;
           &lt;nav name="menulink1child2" path="menulink2childlink2.php"&gt;
              &lt;nav name="menulink2child2child2"
                   path="menulink2childlink2childlink2.php" /&gt;
           &lt;/nav&gt;
        &lt;/nav&gt;
  
        &lt;nav name="menulink3" path="link3.php"&gt;
           &lt;nav name="menulink3child3" path="menulink3childlink3.php"&gt;
               &lt;nav name="menulink3child3child3"
                    path="menulink3childlink3childlink3.php" /&gt;
           &lt;/nav&gt;
        &lt;/nav&gt;
  
        &lt;nav name="menulink4" path="link4.php"&gt;
           &lt;nav name="menulink4child4"
                path="menulink4childlink4.php"&gt;
               &lt;nav name="menulink4child4child4"
                 path="menulink4childlink4childlink4.php" /&gt;
           &lt;/nav&gt;
        &lt;/nav&gt;
    &lt;/menu&gt;
  &lt;/root&gt;
  </code></pre>
  
  <p>This basically only shows first tier <code>&lt;nav&gt;</code> children based on param "$page".
  Example(s) of how the menu works and which nodes selected, basically aligned <code>&lt;nav&gt;</code> nodes are children, indented nodes are child of parents and so on etc etc. <a href="http://fraudo.orconhosting.net.nz/xml.png" rel="nofollow noreferrer">xml example http://fraudo.orconhosting.net.nz/xml.png</a></p>
  
  <p>TIA
  Jared</p>
  
  <p>Updated code snippet</p>
  
  <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
      &lt;xsl:output method="html" /&gt;
      &lt;xsl:param name="page" select="'index.aspx'"/&gt;
  
      &lt;xsl:template name="makeUL"&gt;
          &lt;ul class="level-2 current-menu"&gt;
              &lt;xsl:apply-templates/&gt;
          &lt;/ul&gt;
      &lt;/xsl:template&gt;
      &lt;xsl:template match="nav"&gt;
  
              &lt;li&gt;
              &lt;xsl:if test=".//@path = $page and $page != '/index.aspx'"&gt;
                  &lt;xsl:attribute name="class"&gt;&lt;xsl:text&gt;children-open current-menu-page&lt;/xsl:text&gt;&lt;/xsl:attribute&gt;
               &lt;/xsl:if&gt;
              &lt;a href="{@path}"&gt;
                  &lt;xsl:value-of select="@name" /&gt;
              &lt;/a&gt;
              &lt;xsl:if test=".//@path = $page and $page != '/index.aspx'"&gt;
                   &lt;xsl:call-template name="makeUL"/&gt;
              &lt;/xsl:if&gt;
          &lt;/li&gt;
  
      &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>I also echo out "ul" before the xml parsing, but I may have that wrong :).</p>
  
  <pre><code>echo '&lt;ul class="level-0 top-level"&gt;'."\n\r";
      echo $xsl-&gt;transformToXML($dom);
  echo '&lt;/ul&gt;'."\n\r";
  </code></pre>