RE: [xsl] XSL resources - Flat to hierarchy - Common ancestors

Subject: RE: [xsl] XSL resources - Flat to hierarchy - Common ancestors
From: "Ben Simkins" <bsimkins@xxxxxxxxxx>
Date: Tue, 27 Jul 2004 12:40:51 +0200
Eureka!
With the answers received, and (I admit) blindly playing around with
templates, I've got something which works for my second question:
I'm posting the entire stylesheet here in case anyone needs it, and also
in case anyone higher up the learning tree has any comments on how it
should be done.

> 2. Transforming 'flat' structures to hierarchies:
> I've adapted a stylesheet found in this list, for creating the
hierarchy
> of this:
> <Menus>
>   <Menu MenuId="58" MenuName="LeftMenu"/>
>   <Menu MenuId="1" MenuParentId="58" MenuName="Home"/>
>   <Menu MenuId="60" MenuParentId="1" MenuName="About us/>
>   ...etc
> </Menus>
>
> Question: is there any way of also adding the numbering (<xsl:number
> level="multiple" format="1.1"/>) directly, or do I have to run the
> output through a second stylesheet?
My answer is:
<?xml version="1.0"?>
<!--XSL to Transform 'flat' Menu structure into hierarchy (expects
format <Menus><Menu MenuId="1" MenuParentId="58"
MenuName="Home"/></Menus>)-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
omit-xml-declaration="no" standalone="no" indent="yes" />

<xsl:template match="/">
  <xsl:variable name="menus">
	<xsl:apply-templates select="Menus"/>
  </xsl:variable>
  <xsl:apply-templates select="msxsl:node-set($menus)/*" mode="addTOC"/>
</xsl:template>

<xsl:template match="Menus">
  <xsl:copy>
    <xsl:apply-templates select="Menu[not(@MenuParentId)]">
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="Menu">
  <xsl:copy>
  	<xsl:copy-of select="@*"/>
    <xsl:if test="count(../Menu[@MenuParentId = current()/@MenuId])">
      <xsl:attribute name="hasChild">true</xsl:attribute>
    </xsl:if>
  	<xsl:apply-templates select="../Menu[@MenuParentId =
current()/@MenuId]"/>
  </xsl:copy>
</xsl:template>

<!--Last template to process results of others and add toc-->
<xsl:template match="Menu" mode="addTOC">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:attribute name="TOC">
        <xsl:number level="multiple" format="1.1"/>
      </xsl:attribute>
      <xsl:apply-templates select="Menu" mode="addTOC"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Current Thread