xsl-list
[Top] [All Lists]

RE: XSL resources - Flat to hierarchy - Common ancestors

2004-07-27 03:40:51
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[(_at_)MenuParentId = current()/@MenuId])">
      <xsl:attribute name="hasChild">true</xsl:attribute>
    </xsl:if>  
        <xsl:apply-templates select="../Menu[(_at_)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>