Hi Anna,
Trying to structure a flat XML into smething more structure based on certain
'start' elements can be tricky - and the XPaths get a bit compicated ;) but
try something like...
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="body">
<xsl:copy>
<xsl:apply-templates select="h1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(local-name(),'h') and
number(substring(local-name(),2)) = number(substring(local-name(),2))]">
<xsl:variable name="level" select="number(substring(name(),2))"/>
<xsl:element name="level{$level}">
<xsl:copy-of select="."/>
<xsl:variable name="this-name" select="local-name()"/>
<xsl:variable name="this-id" select="generate-id()"/>
<xsl:variable name="next-name" select="concat('h',$level + 1)"/>
<xsl:apply-templates
select="following-sibling::node()[generate-id(preceding-sibling::*[starts-wi
th(local-name(),'h') and number(substring(local-name(),2)) =
number(substring(local-name(),2))][1]) = $this-id and
not(starts-with(local-name(),'h') and number(substring(local-name(),2)) =
number(substring(local-name(),2)))] |
following-sibling::*[local-name() =
$next-name][generate-id(preceding-sibling::*[local-name() = $this-name][1])
= $this-id]"/>
</xsl:element>
</xsl:template>
<xsl:template match="@* | text() | comment() | processing-instruction()">
<xsl:copy/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="no_level"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="no_level">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="no_level"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | text() | comment() | processing-instruction()"
mode="no_level">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
HTH
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator
"Anna" <an**@ubaccess.com> wrote in message
news:8e**************************@posting.google.c om...
Hi all.
I am trying to write a stylesheet that will structure the input HTML
file in the following way:
For each heading of level n it needs to enclose the heading and all
its content until the next heading of the same level within the level
tag.
Example
input file:
<body>
<h1>First heading</h1>
Some text for first heading.
<h2>Second heading</h2>
<p>Some text for second heading</p>
<h3>Small heading</h3>
<div>Small text</div>
<h1>Another big heading</h1>
<span>Some text for big heading</span>
<h2>Sub heading for second big heading</h2>
</body>
output file:
<body>
<level1>
<h1>First heading</h1>
Some text for first heading.
<level2>
<h2>Second heading</h2>
<p>Some text for second heading</p>
<level3>
<h3>Small heading</h3>
<div>Small text</div>
</level3>
</level2>
</level1>
<level1>
<h1>Another big heading</h1>
<span>Some text for big heading</span>
<level2>
<h2>Sub heading for second big heading</h2>
</level2>
</level1>
</body>
I am trying to build an xsl which will call apply-templates for inner
elements with another mode, but fail to do it cleanly - I get a lot of
text nodes output multiple times.
Is there a neat way to do such a thing?
Thank you very much for help and sorry if this is an inapropriate
question.
Anna