At 2008-06-16 01:46 +0700, Ivan Shmakov wrote:
I wonder, what would be the simplest way to transform a sequence
of sibling nodes, e. g.:
...
into a nested list, like:
...
in XSLT 1.0?
The following conditions are assumed to be true:
* all the `hN' nodes are the children of a single `body' node;
* for any consequent elements `hN' and `hM', M <= 1 + N; the
first child of the `body' node is `h1'; i. e., it's assumed
that, e. g., the following input could never happen:
<body>
<h1>Foo</h1>
<h3>Bar</h3>
</body>
Those criteria you state make this quite straightforward ... the
stylesheet below addresses these quite succinctly. You don't mention
where you are having problems in your stylesheet so I'm not sure
where to advise. I don't think your indentation is significant so I
didn't try to copy the indentation in my solution.
This approach takes advantage of the ability to have multiple
declarations for the same key table. This is different from
approaches I've taken in the past as I thought this might be far more
straightforward than trying to descend recursively ... since your
give the criterion that no levels of nesting are going to be missed
in the input.
I hope this helps.
. . . . . . . . . . . Ken
t:\ftemp>type ivan.xml
<body>
<h1>Chapter</h1>
<h2>Section</h2>
<h3>Subsection</h3>
<h3>Another subsection</h3>
<h2>Another section</h2>
</body>
t:\ftemp>type ivan.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<!--for each possible child, indicate who they are a child of-->
<xsl:key name="nested" match="h2" use="generate-id(preceding-sibling::h1[1])"/>
<xsl:key name="nested" match="h3" use="generate-id(preceding-sibling::h2[1])"/>
<xsl:key name="nested" match="h4" use="generate-id(preceding-sibling::h3[1])"/>
<xsl:key name="nested" match="h5" use="generate-id(preceding-sibling::h4[1])"/>
<xsl:key name="nested" match="h6" use="generate-id(preceding-sibling::h5[1])"/>
<!--get things started-->
<xsl:template match="body">
<xsl:copy>
<ul>
<xsl:apply-templates select="h1"/>
</ul>
</xsl:copy>
</xsl:template>
<!--for each layer, show title and present only the children-->
<xsl:template match="h1|h2|h3|h4|h5|h6">
<li>
<!--this does the title-->
<xsl:apply-templates/>
<!--this does the children (if they exist)-->
<xsl:variable name="children" select="key('nested',generate-id(.))"/>
<xsl:if test="$children">
<ul>
<xsl:apply-templates select="$children"/>
</ul>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>xslt ivan.xml ivan.xsl con
<?xml version="1.0" encoding="utf-8"?>
<body>
<ul>
<li>Chapter<ul>
<li>Section<ul>
<li>Subsection</li>
<li>Another subsection</li>
</ul>
</li>
<li>Another section</li>
</ul>
</li>
</ul>
</body>
t:\ftemp>
--
Upcoming XSLT/XSL-FO hands-on courses: Wellington, NZ 2009-01
World-wide corporate, govt. & user group XML, XSL and UBL training
RSS feeds: publicly-available developer resources and training
G. Ken Holman mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers: http://www.CraneSoftwrights.com/legal
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--