Re: [xsl] Hierarchy based on indentation (long)

Subject: Re: [xsl] Hierarchy based on indentation (long)
From: Grainne Reilly <greilly1@xxxxxxxxx>
Date: Tue, 10 Dec 2002 02:32:53 -0500
Thanks Dimitre for this approach which certainly is more comprehendible than my original. I can't rely on the number of spaces per indentation level being consistent, I can only rely on each indentation level having the same number of spaces. I have made an attempt to adapt your code to cover that (see below).

Grainne.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:saxon="http://icl.com/saxon";
xmlns:exsl="http://exslt.org/common";
extension-element-prefixes="exsl saxon">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/">
<xsl:variable name="vSortedRows">
<xsl:apply-templates select="/*/row" mode="sort">
<xsl:sort data-type="number" select="string-length(substring-before(cell,substring(normalize-space(cell), 1,1)))"/>
</xsl:apply-templates>
</xsl:variable>


<xsl:variable name="vtLevels">
<xsl:call-template name="getLevels">
<xsl:with-param name="pSortedRows" select="exsl:node-set($vSortedRows)/row"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="vLevels" select="exsl:node-set($vtLevels)"/>


<xsl:for-each select="/*/row">
<xsl:variable name="vThisIndent" select="string-length(substring-before(cell,substring(normalize-space(cell), 1,1)))"/>
<descriptions>
<xsl:call-template name="genDescription">
<xsl:with-param name="pNode" select="."/>
<xsl:with-param name="pRow" select="position()"/>
<xsl:with-param name="pLevels" select="$vLevels"/>
<xsl:with-param name="pLevel" select="$vLevels/level[@indent = $vThisIndent]/@num"/>
</xsl:call-template>
</descriptions>
</xsl:for-each>
</xsl:template>


<xsl:template match="row" mode="sort">
        <xsl:copy-of select="."/>
</xsl:template>

<xsl:template name="getLevels">
<xsl:param name="pSortedRows" select="/.."/>
<xsl:param name="pLevelNumber" select="1"/>
<xsl:variable name="vThisIndent" select="string-length(substring-before($pSortedRows[1]/cell,substring(normalize-space($pSortedRows[1]/cell), 1,1)))"/>
<xsl:variable name="vNext" select="$pSortedRows/following-sibling::row[string-length(substring-before(cell,substring(normalize-space(cell), 1,1))) > $vThisIndent ]" />


<level num="{$pLevelNumber}" indent="{$vThisIndent}"/>

<xsl:if test="$vNext">
<xsl:call-template name="getLevels">
<xsl:with-param name="pSortedRows" select="$vNext"/>
<xsl:with-param name="pLevelNumber" select="$pLevelNumber + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>


<xsl:template name="genDescription">
    <xsl:param name="pNode" select="/.."/>
    <xsl:param name="pRow" />
    <xsl:param name="pLevel"/>
    <xsl:param name="pLevels" select="/.."/>

<xsl:if test="$pLevel > 1">
<xsl:variable name="vindentParent" select="$pLevels/level[@num = ($pLevel - 1)]/@indent"/>


<xsl:variable name="vParent"
select="preceding-sibling::row[ cell[ string-length(substring-before(.,substring(normalize-space(.), 1,1))) = $vindentParent ] ][1]"/>


    <xsl:call-template name="genDescription">
      <xsl:with-param name="pNode" select="$vParent"/>
      <xsl:with-param name="pRow" select="$pRow"/>
      <xsl:with-param name="pLevel" select="$pLevel - 1"/>
      <xsl:with-param name="pLevels" select="$pLevels"/>
    </xsl:call-template>
  </xsl:if>


<description row="{$pRow}" level="{$pLevel}"> <xsl:value-of select="$pNode/cell"/> </description>

</xsl:template>

</xsl:stylesheet>


<snip/>


Hi Grainne,

It seems to me that the following solution is simpler. It uses a
recursively called named template to generate the descriptions, and
also the fact that the indent for every next level is 3:

<snip/>

=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread