Re: Complex table of content generation

Subject: Re: Complex table of content generation
From: Jean-Claude Tarby <Jean-Claude.Tarby@xxxxxxxxxxxxx>
Date: Thu, 29 Jun 2000 18:48:10 +1000
Jeni is God ! 

Your solution is excellent !! Simple and very fast ! You can have a look at
mine at the end of this email to compare :-((  .

But, I still have 2 problems/questions :

>3. by human choice
><xsl:param name="top-component" select="'C'" />
>...

I was not clear in my previous email. Your template is excellent to provide
the logical order in 3 levels. But my trees may have some branches with
3-depth levels, some other branches with 10-depth levels, some others with
25-depth levels, and so on. 

How to improve your template to produce the logical order with ALL the
different depth-levels ? The stopping condition is : we stop to explore a
branch when we find a component name which is a component which has
subcomponents. This is because if Cx contains Cy which contains Cx, the
last Cx cannot contain something. I think that if it was possible to
decompose again the last Cx, it would be impossible to write the associated
XML document, or that means that we can have two differents elements Cx...

Stopping condition examples (cf. tree below):
* C2 : C2 has subcomponents, so we explore it. But in its subcomponents, we
find C4 (not yet explored!!!). But C4 has subcomponents, so we stop the
exploration
* C3 : C3 has subcomponents, so we explore it. But in its subcomponents, we
find C3 again. So we stop the exploration each time we find C3
* C4 : C4 has subcomponents, so we explore it. But in its subcomponents, we
find C2.1 which has subcomponents. So we stop the exploration. Same for C
and C4.

Anyway, can you give me 2 solutions for the following tree? One when the
stopping solution is "we find a component name which was already
processed", and one when the stopping solution is "we find a component name
which is a component which has subcomponent". I'd like these two solutions
(if possible, or at least the second one) to understand how you store and
manage already parsed components.

                                C
                                |
    |------------------|-----------------|------------------|
    C1                 C2                C3                 C4
    |                  |                 |                  |
  |-----|        |-----|----|       |---|--|--|       |----|----|---|
C1.1  C1.2     C2.1  C2.2  C4     C1.1 C2 C3 C3.1    C1.1 C2.1  C   C4
        |        |                            | 
      C1.2.1   C2.1.1                      |-----|
                 |                        C3   C3.1.1
            |---------|
         C2.1.1.1   C2.1.1.2     



The result for the logical order should be :
C, C1, C1.1
C, C1, C1.2, C1.2.1
C, C2, C2.1, C2.1.1, C2.1.1.1 - C2.1.1.2
C, C2, C2.2
C, C2, C4
C, C3, C1.1
C, C3, C2
C, C3, C3
C, C3, C3.1, C3 - C3.1.1
C, C4, C1.1
C, C4, C2.1
C, C4, C
C, C4, C4


>>2.2 Description of each component (each name is a hyperlink, too)

Excellent solution again. But you may have the same result as me. Sometimes
(not necessary here) results are like A,B,B,C,C,C,D,D and we want just
A,B,C,D. Is it possible to delete the identical elements during the
processing? I suppose that a simpler solution is to write a second
stylesheet which does this deletion, but how to delete the identical
elements inside the process of your stylesheet?

>I have used xsl:for-each in these examples both for brevity and because the
>definition of the output you wanted from the logical order seemed to be in
>terms of 'depth', which is easier to manage with xsl:for-each than
>xsl:apply-templates.  However, if you can define the stopping condition
>(i.e. when do you stop going down a branch?) in terms of things that you
>know about a particular component (e.g. has it got a longer name than its
>parent?), then you could (should?) probably use xsl:apply-templates instead.

I didn't understand this part. Can you explain me ? May be your new
solution will apply this part ?

Anyway, thanks a lot for your help. I really understood a lot of things
about XSLT. 

I hope that you'll give an answer to this email.

Best regards,

J.C.

----------- My previous solution 

STYLESHEET:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>


<xsl:output method = "html" />

<xsl:key name = "ref" match = "Component" use = "@Name" />

<xsl:template match="/">
  <html>
    <head>
      <title>TOC</title>
    </head>
    <body>
      <xsl:for-each select = "Components/Component">
      <xsl:sort select = "@Name"/>
         <xsl:apply-templates select = "."/>
      </xsl:for-each>
    </body>
  </html>
</xsl:template>
    

        <xsl:template match="Component">
          <p>
            <xsl:text>Component : </xsl:text> 
            <b><a name="{generate-id()}"><xsl:value-of select="@Name"
/></a></b>
          </p>
          <ul>
           <li>
            <xsl:text> parent(s) : </xsl:text>
            
             <xsl:variable name = "nom"><xsl:value-of select="@Name"
/></xsl:variable>
             
              <xsl:for-each select = "/Components/Component/Link[.=$nom]">
              <xsl:sort select = "../@Name"/>
		<a href = "#{generate-id(key('ref',../@Name))}"><xsl:value-of select =
"../@Name"/> </a>
              <xsl:text> </xsl:text>
              </xsl:for-each>
            </li>           
            <li>
              <xsl:text> subComponents : </xsl:text>
                <xsl:for-each select = " SubComponent">
                <xsl:sort select = "text()"/>
                   <a href = "#{generate-id(key('ref',.))}">
                   <xsl:apply-templates/>
                   </a>
                   <xsl:text>,</xsl:text>
                </xsl:for-each>
            </li>
           </ul>
       </xsl:template>
        
       <xsl:template match="SubComponent">
          <a href = "#{generate-id(key('ref',.))}">
          <xsl:apply-templates />
          </a>
       </xsl:template>
        
</xsl:stylesheet>

XML Document:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Components SYSTEM ".\Components.dtd">
<Components>
	<Component Name="C">
		<SubComponent>C1</SubComponent>
		<SubComponent>C2</SubComponent>
		<SubComponent>C3</SubComponent>
		<SubComponent>C4</SubComponent>
	</Component>
	<Component Name="C1">
		<SubComponent>C1_1</SubComponent>
		<SubComponent>C1_2</SubComponent>
	</Component>
	<Component Name="C2">
		<SubComponent>C2_1</SubComponent>
		<SubComponent>C2_2</SubComponent>
		<SubComponent>C4</SubComponent>
	</Component>
	<Component Name="C3">
		<SubComponent>C1_1</SubComponent>
		<SubComponent>C2</SubComponent>
		<SubComponent>C3</SubComponent>
    	<SubComponent>C3_1</SubComponent>
	</Component>
	<Component Name="C4">
       	<SubComponent>C1_1</SubComponent>
		<SubComponent>C2_1</SubComponent>
		<SubComponent>C</SubComponent>
		<SubComponent>C4</SubComponent>
	</Component>
	<Component Name="C1_1">
       	<SubComponent>none</SubComponent>
	</Component>
	<Component Name="C1_2">
       	<SubComponent>C1_2_1</SubComponent>
	</Component>
	<Component Name="C2_1">
       	<SubComponent>C2_1_1</SubComponent>
	</Component>
	<Component Name="C2_2">
       	<SubComponent>none</SubComponent>
	</Component>
	<Component Name="C3_1">
       	<SubComponent>C3</SubComponent>
       	<SubComponent>C3_1_1</SubComponent>
	</Component>
	<Component Name="C1_2_1">
       	<SubComponent>none</SubComponent>
	</Component>
	<Component Name="C2_1_1">
       	<SubComponent>C2_1_1_1</SubComponent>
       	<SubComponent>C2_1_1_2</SubComponent>
	</Component>
	<Component Name="C3_1_1">
       	<SubComponent>none</SubComponent>
	</Component>
	<Component Name="C2_1_1_1">
       	<SubComponent>none</SubComponent>
	</Component>
	<Component Name="C2_1_1_2">
       	<SubComponent>none</SubComponent>
	</Component>
</Components>


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


Current Thread