Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developersí questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old June 21st, 2007, 10:55 AM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default Regarding Table of Contents Creation

Hi All,

I'm new to XSLT, so here's my first problem. I'm attempting at automatically created a Table of Contents. I'm having problems creating the correct number to the left of the heading. For example, this is the output I want (given the example XML data provided):
1 This is a heading
2 This is another heading
  2.1 This is a subheading
    2.1.1 This is a sub-subheading
    2.1.2 This is a sub-subheading2
3 This is yet another heading

I have XML data which would be in the format of (the level attribute defines the level of indentation):
Code:
<structure level="1">
  <header>This is a heading</header>
  ...
</structure>
<structure level="1">
  <header>This is another heading</header>
  ...
</structure>
<structure level="2">
  <header>This is a subheading</header>
  ...
</structure>
<structure level="3">
  <header>This is a sub-subheading</header>
  ...
</structure>
<structure level="3">
  <header>This is a sub-subheading2</header>
  ...
</structure>
<structure level="1">
  <header>This is yet another heading</header>
  ...
</structure>
So far I have messed around with both using the count function and using xsl:number. I'm nowhere close, so figured I would ask for pointers. A snippit of my current xslt looks like this:
Code:
<xsl:for-each select="structure">
  <xsl:value-of select="1 + count(preceding::structure)"/>
  <xsl:value-of select="./header"/>
</xsl:for-each>
However, the output looks like this:
1 This is a heading
2 This is another heading
  3 This is a subheading
    4 This is a sub-subheading
    5 This is a sub-subheading2
6 This is yet another heading

Thanks in advance,
Jesse
Reply With Quote
  #2 (permalink)  
Old June 21st, 2007, 11:05 AM
mhkay's Avatar
Wrox Author
Points: 18,252, Level: 58
Points: 18,252, Level: 58 Points: 18,252, Level: 58 Points: 18,252, Level: 58
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,929
Thanks: 0
Thanked 281 Times in 276 Posts
Default

Not an easy one. Can you use XSLT 2.0 or do you have constraints that tie you to 1.0?

The basic problem is that the hierarchic structure is implicit in the level numbers rather than being explicit in the markup. One approach is to first convert to a proper hierarchic structure; see http://www.idealliance.org/proceedin...mhk-paper.html for an example of doing that in XSLT 2.0. Or search for "XSLT positional grouping" for 1.0 solutions.

I think any 1.0 solution is going to involve a recursive walk up the (logical) tree.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #3 (permalink)  
Old June 21st, 2007, 11:45 AM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Unfortunately I'm stuck with 1.0. I think I might have a solution, so I'm going to give it a go. I'll post back soon hopefully with some more feedback.

Thanks

Reply With Quote
  #4 (permalink)  
Old June 21st, 2007, 12:15 PM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

As part of my solution I'm attempting to modify the DOM tree by adding a new attribute to the structure element. However, this snippit of code does not seem to be working...any ideas why?

Code:
 
<xsl:for-each select="structure">
  <xsl:copy>
    <xsl:attribute name="idToc">BLA</xsl:attribute>
  </xsl:copy>
</xsl:for-each>
Reply With Quote
  #5 (permalink)  
Old June 21st, 2007, 01:17 PM
mhkay's Avatar
Wrox Author
Points: 18,252, Level: 58
Points: 18,252, Level: 58 Points: 18,252, Level: 58 Points: 18,252, Level: 58
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,929
Thanks: 0
Thanked 281 Times in 276 Posts
Default

There's nothing wrong with that snippet. You error lies elsewhere.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #6 (permalink)  
Old June 21st, 2007, 02:05 PM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I will probably have to figure out where the error lies.

On a side note:
I can't determine if the
Code:
<xsl:copy>
is necessary though. I've been trying to read up on exactly what copy does, but it's still a bit hazy. Is this creating a completely separate DOM where the node that I copy can be modified?

Reply With Quote
  #7 (permalink)  
Old June 21st, 2007, 02:44 PM
mhkay's Avatar
Wrox Author
Points: 18,252, Level: 58
Points: 18,252, Level: 58 Points: 18,252, Level: 58 Points: 18,252, Level: 58
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,929
Thanks: 0
Thanked 281 Times in 276 Posts
Default

XSLT always creates a new document by transforming the input document. The input document is never modified. xsl:copy creates a new element as a copy of the current element.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #8 (permalink)  
Old June 21st, 2007, 03:04 PM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Below is the portion of current code that I'm working on. I can't figure out why the first part of this script does not set each structure's "level" attribute to 10. Any ideas why?

Code:
       <xsl:for-each select="structure">
            <copy>
                <xsl:copy-of select="@*"/>
                <xsl:attribute name="level">10</xsl:attribute>
            </copy>
        </xsl:for-each>


        <div class="header"  id="tableOfContents" onclick="arrowFlip(this);flip('tableOfContentsBody');" style="cursor:pointer;">
            Table of Contents
        </div>
        <div class="body" id="tableOfContentsBody">
            <xsl:for-each select="structure">            
                <xsl:variable name="level"><xsl:value-of select="./@level"/></xsl:variable>
                <xsl:variable name="header"><xsl:value-of select="./header"/></xsl:variable>
                <xsl:choose>
                    <xsl:when test="$level=1">
                        <div class="tocHeader">
                            <b><a href="#{$header}Anchor{generate-id(.)}">



                            <span style="margin-left:16px"><xsl:value-of select="./header"/></span>
                            </a></b>
                        </div>
                    </xsl:when>
                    <xsl:otherwise>
                        <div style="padding-left:{$level*15-15}px;">
                            <a href="#{$header}Anchor{generate-id(.)}">



                            <span style="margin-left:16px"><xsl:value-of select="./header"/></span>
                            </a>
                        </div>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>

            <div class="miniButtons">
                <a href="javascript:collapseAll();"><img src="{$imageDirectory}../collapse.png" class="miniButtonsImg" />Collapse All</a> | 
                <a href="javascript:expandAll();"><img src="{$imageDirectory}../expand.png" class="miniButtonsImg" />Expand All</a> | 
                <a href="#coverPageAnchor"><img src="{$imageDirectory}../totop.png" class="miniButtonsImg" />Back To Top</a>
            </div>
        </div>
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Table creation sunny227 XSLT 3 November 14th, 2007 01:50 PM
Creation date of a table firefighter2045 Access VBA 4 November 2nd, 2007 10:52 AM
How to display the arraylist contents into a table yzlin04 ASP.NET 2.0 Basics 2 July 27th, 2007 06:23 AM
table of contents light BOOK: Professional Crystal Reports for VS.NET 0 March 9th, 2005 08:45 AM
Table Creation rgerald Access VBA 1 June 24th, 2003 08:01 PM



All times are GMT -4. The time now is 05:02 AM.


Powered by vBulletin®
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.