Although it depends on the application, I would generally agree with Adam. A dedicated XML package would work nicely. Actually, it is pretty much already included with the cart Take a look at the rev.categories.xml.config XML package.
In its original form, this XML package is designed to pull in categories in an unordered list format (<ul><li>...</li></ul). It also pulls in subcategories for the current category being viewed.
If you take a look at the Entity template inside the XML package file - you will notice the following conditional if block:
Code:
<xsl:if test="count(child::Entity)>0 and (EntityID = $CategoryID or descendant::Entity/EntityID = $CategoryID)">
<ul class="tame">
<xsl:apply-templates select="Entity">
<xsl:with-param name="prefix" select="concat($prefix, '  ')"/>
</xsl:apply-templates>
</ul>
</xsl:if>
This block is responsible for performing a recursive call to the Entity template, in order to pull in subcategories. However, the stock XML package has a couple of conditions that limit the subcategories being pulled in, to those that fall under the current category being viewed by the user.
If we modify the test condition, we can have all of the categories & subcategories (and sub-sub categories) display - regardless of the current entity or page being viewed.
To do so, replace the existing conditional block, with the following:
Code:
<xsl:if test="count(child::Entity)>0">
<ul class="tame">
<xsl:apply-templates select="Entity">
<xsl:with-param name="prefix" select="concat($prefix, '  ')"/>
</xsl:apply-templates>
</ul>
</xsl:if>
In conclusion, you should be able to reuse most of the code in the rev.categories.xml.config file to achieve a dynamic unordered list.
For more information on XML packages, see this extensive article from the storefront manual: http://manual.aspdotnetstorefront.co...-packages.aspx
Hope that helps. Please let me know if you have any questions.