[
Lists Home |
Date Index |
Thread Index
]
- To: xml-dev@lists.xml.org
- Subject: Constructing Tree using XSLT
- From: Hugo Jose Ferreira <bytter@netcabo.pt>
- Date: Sat, 13 Sep 2003 05:00:40 +0100
- User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.5b) Gecko/20030901 Thunderbird/0.2
Hi everyone,
Could someone help me here? I'm trying to construct a graphical tree
using XML/XSLT. Here's what I'm doing:
1. Have a XML tree structure, with the correspondent tree. i.e.:
<treemenu title='Sample Tree'>
<item href='test1.php' title='First Item'/>
<item href='test2.php' title='Second Item'>
<item href='subtest1.php' title='First Subtitle'/>
<item href='subtest2.php' title='Second Subtitle'>
<item href='subsubtest1.php' title='First Subsubtitle'/>
</item>
</item>
<item href='test3.php' title='Third Item'/>
</treemenu>
2. Do the parse using the following algorithm: Call a recursive function
that, for each item, make the necessary blank spaces (for identantion)
and then print the item. Here's the sample XSL:
<xsl:template match='treemenu'>
<div class='treemenu'>
<h1><xsl:value-of select='@title' /></h1>
<div>
<xsl:apply-templates select='item'>
<xsl:with-param name="depth" select="0"/>
</xsl:apply-templates>
</div>
</div>
</xsl:template>
<xsl:template match='item'>
<xsl:param name="depth"/>
<xsl:call-template name='makespace'>
<xsl:with-param name="depth" select="$depth"/>
</xsl:call-template>
<xsl:for-each select='.'>
<xsl:variable name="pos" select='count(../preceding-sibling::node())
+ 1' />
<xsl:variable name="total" select='count(preceding-sibling::item)' />
<xsl:choose>
<xsl:when test="count(item)">
<img src='images\folder.gif' />
</xsl:when>
<xsl:otherwise>
<img src='images\page.gif' />
</xsl:otherwise>
</xsl:choose>
<xsl:if test='@href'>
<a href='{@href}'><xsl:value-of select='@title' /></a>
</xsl:if><xsl:if test='not(@href)'>
<xsl:value-of select='@title' />
</xsl:if><br />
<xsl:apply-templates select='item'>
<xsl:with-param name="depth" select="$depth + 1"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template name='makespace'>
<xsl:param name="depth"/>
<xsl:if test="$depth > 0">
<img src='images\empty.gif'/>
<xsl:call-template name='makespace'>
<xsl:with-param name="depth" select="$depth + (-1)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
So far so good. But this does not print the vertical lines that connect
items. Why? Well, I could use the empty.gif as a vertical line. I could
even check if the item was the last one in the list, and do an 'L'
shaped line, and not a 'T' one. BUT, the problem is that in some cases
there ARE no vertical lines to connect, because there are not more items
to the bottom.
When does this happen? Simple... Whenever the parent of an item doesn't
have any brother that follows him. How? Checking the current parent
position of the parsing, and comparing to the total items on that level
(I've done some variables in the main template, $pos and $total, that do
that. So, what's the solution? Well... Probably to use a XPointer/Xpath
expression in the 'makespace' tamplate that would check (according to
$depth) this statement in the source XML tree, and choose the proper
image to display. My problem is: I can't build it :) So, could anyone
PLEEEASSSEE give me an help here? It would be very appreciated!
Also, if anyone knows a faster, cleaner and elegant way to do this and
would like to share with me, I would be very appreciated too...
My best regards too all, and thanks in advance,
Hugo Jose Ferreira
|