Hi,
using XSLT 2.0 this does what you want (somebody might improve this since
grouping feels still new to me):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="/">
<body>
<xsl:for-each-group select="/body/*"
group-starting-with="*[not(@class = ('listitembullets',
'listitemindented'))]">
<xsl:copy-of select="."/>
<xsl:call-template name="list"/>
</xsl:for-each-group>
</body>
</xsl:template>
<xsl:template name="list">
<xsl:if test="current-group()[2]">
<ul>
<xsl:variable name="cl" select="current-group()[2]/@class"/>
<xsl:for-each-group select="current-group() except ."
group-starting-with="p[@class = $cl]">
<li>
<xsl:value-of select="text()"/>
<xsl:call-template name="list"/>
</li>
</xsl:for-each-group>
</ul>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Output:
<body>
<p class="listintro">ListItem_Bullets:</p>
<ul>
<li> Item 1</li>
<li> Item 2</li>
<li> Item 3</li>
</ul>
<p class="normal">Paragraph within a list.</p>
<ul>
<li> Item 4</li>
<li> Item 5
<ul>
<li> Item 1 indented</li>
<li> Item 2 indented</li>
</ul>
</li>
<li> Item 6</li>
</ul>
<h2>Indented list starts here:</h2>
<ul>
<li> Item 1 indented</li>
<li> Item 2 indented</li>
<li> Item 3 indented</li>
</ul>
<p class="normal">Paragraph within a list.</p>
<ul>
<li> Item 4 indented</li>
<li> Item 5 indented</li>
<li> Item 6 indented</li>
</ul>
</body>
Heiko
> Hi,
>
> I have this for my input XML:
>
> <body>
> <p class="listintro">ListItem_Bullets:</p>
> <p class="listitembullets">• Item 1</p>
> <p class="listitembullets">• Item 2</p>
> <p class="listitembullets">• Item 3</p>
> <p class="normal">Paragraph within a list.</p>
> <p class="listitembullets">• Item 4</p>
> <p class="listitembullets">• Item 5</p>
> <p class="listitemindented">• Item 1 indented</p>
> <p class="listitemindented">• Item 2 indented</p>
> <p class="listitembullets">• Item 6</p>
> <h2>Indented list starts here:</h2>
> <p class="listitemindented">• Item 1 indented</p>
> <p class="listitemindented">• Item 2 indented</p>
> <p class="listitemindented">• Item 3 indented</p>
> <p class="normal">Paragraph within a list.</p>
> <p class="listitemindented">• Item 4 indented</p>
> <p class="listitemindented">• Item 5 indented</p>
> <p class="listitemindented">• Item 6 indented</p>
> </body>
>
> I want to get this:
>
> <body>
> <p class="listintro">ListItem_Bullets:</p>
> <ul>
> <li>Item 1</li>
> <li>Item 2</li>
> <li>Item 3</li>
> </ul>
> <p class="normal">Paragraph within a list.</p>
> <ul>
> <li>Item 4</li>
> <li>Item 5</li>
> <ul>
> <li>Item 1 indented</li>
> <li>Item 2 indented</li>
> </ul>
> <li>Item 6</li>
> </ul>
> <h2>Indented list starts here:</h2>
> <ul>
> <li>. Item 1 indented</li>
> <li>. Item 2 indented</li>
> <li>. Item 3 indented</li>
> </ul>
> <p class="normal">Paragraph within a list.</p>
> <ul>
> <li>. Item 4 indented</li>
> <li>. Item 5 indented</li>
> <li>. Item 6 indented</li>
> </ul>
> </body>
>
> I am actually getting this:
>
> <body>
> <p class="listintro">ListItem_Bullets:</p>
> <ul>
> <li>Item 1</li>
> <li>Item 2</li>
> <li>Item 3</li>
> </ul>
> <p class="normal">Paragraph within a list.</p>
> <ul>
> <li>Item 4</li>
> <li>Item 5</li>
> </ul>
> <h2>Indented list starts here:</h2>
> <ul>
> <li>. Item 1 indented</li>
> <li>. Item 2 indented</li>
> <li>. Item 3 indented</li>
> </ul>
> <p class="normal">Paragraph within a list.</p>
> <ul>
> <li>. Item 4 indented</li>
> <li>. Item 5 indented</li>
> <li>. Item 6 indented</li>
> </ul>
> </body>
>
> The problem is that I have some different list items represented by the
> various class attributes. I tried to get cute with keys. It works for all
> of
> the lists except the "listitemindented" lists. Here is my stylesheet. Any
> help will be appreciated. (Forget about the bullets; I can solve that
> separately.)
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> xmlns:xhtml="http://www.w3.org/1999/xhtml"
> xmlns="http://www.w3.org/1999/xhtml"
> exclude-result-prefixes="xhtml xsl"
> version="1.0">
>
> <xsl:key name="orderedlists" match="xhtml:p[@class='listitem1' or
> @class='listitem2']"
> use="generate-id((..|preceding-sibling::*[not(self::xhtml:p[@class='listitem
> 1' or @class='listitem2'])][1])[last()])"/>
> <xsl:key name="unorderedlists-plain"
> match="xhtml:p[@class='listitemunordered']"
> use="generate-id((..|preceding-sibling::*[not(self::xhtml:p[@class='listitem
> unordered'])][1])[last()])"/>
>
> <xsl:key name="unorderedlists"
> match="xhtml:p[@class='listitembullets']"
> use="generate-id((..|preceding-sibling::*[not(self::xhtml:p[@class='listitem
> bullets'])][1])[last()])"/>
> <xsl:key name="unorderedlists-indented"
> match="xhtml:p[@class='listitemindented']"
> use="generate-id((..|preceding-sibling::*[not(self::xhtml:p[@class='listitem
> indented'])][1])[last()])"/>
>
> <xsl:output indent="yes"/>
>
> <!--this is a construct whose children need to be grouped in separate
> lists-->
> <xsl:template match="xhtml:body">
> <body>
> <xsl:apply-templates mode="group"
> select=".|*[not(self::xhtml:p[@class='listitem1' or @class='listitem2' or
> @class='listitemunordered' or @class='listitembullets' or
> @class='listitemindented'])]"/>
> </body>
> </xsl:template>
>
> <xsl:template mode="group" match="*">
> <xsl:apply-templates select="self::*[not(self::xhtml:body)]"/>
> <xsl:if test="key('orderedlists',generate-id(.))">
> <ol
> start="{substring-before(following-sibling::*/node(),'.')}">
> <xsl:apply-templates
> select="key('orderedlists',generate-id(.))"/>
> </ol>
> </xsl:if>
> <xsl:if test="key('unorderedlists-plain',generate-id(.))">
> <dl>
> <xsl:apply-templates
> select="key('unorderedlists-plain',generate-id(.))"/>
> </dl>
> </xsl:if>
> <xsl:if test="key('unorderedlists-indented',generate-id(.))">
> <ul>
> <xsl:apply-templates
> select="key('unorderedlists-indented',generate-id(.))"/>
> </ul>
> </xsl:if>
> <xsl:if test="key('unorderedlists',generate-id(.))">
> <ul>
> <xsl:apply-templates
> select="key('unorderedlists',generate-id(.))"/>
> </ul>
> </xsl:if>
> </xsl:template>
>
> <!--the following template rules need no knowledge of grouping-->
>
> <xsl:template match="xhtml:p[@class='listitem1' or
> @class='listitem2']">
> <li><xsl:apply-templates/></li>
> </xsl:template>
>
> <xsl:template match="xhtml:p[@class='listitem1' or
> @class='listitem2']/text()[1]">
> <xsl:value-of select="substring-after(.,'. ')"/>
> </xsl:template>
>
> <xsl:template match="xhtml:p[@class='listitembullets' or
> @class='listitemindented']">
> <li><xsl:apply-templates/></li>
> </xsl:template>
>
> <xsl:template match="xhtml:p[@class='listitemunordered']">
> <dd><xsl:apply-templates/></dd>
> </xsl:template>
>
> <xsl:template match="xhtml:p[@class='listitembullets']/text()[1]">
> <xsl:value-of select="substring-after(.,'• ')"/>
> </xsl:template>
>
> <!-- IdentityTransform -->
> <xsl:template match="/ | @* | node()" name="identity">
> <xsl:copy><xsl:apply-templates select="@* | node()" /></xsl:copy>
> </xsl:template>
>
> </xsl:stylesheet>
|