Subject: RE: [xsl] Nested lists From: "Rick Quatro" <rick@xxxxxxxxxxxxxx> Date: Thu, 31 Oct 2013 21:05:30 -0400 |
Hi Heiko, Thanks. I am using MSXML so I have to do this with XSLT 1.0. Rick -----Original Message----- From: Heiko Niemann [mailto:kontakt@xxxxxxxxxxxxxxxx] Sent: Thursday, October 31, 2013 8:13 PM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: [xsl] Nested lists 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='li > stitem 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='li > stitem > unordered'])][1])[last()])"/> > > <xsl:key name="unorderedlists" > match="xhtml:p[@class='listitembullets']" > use="generate-id((..|preceding-sibling::*[not(self::xhtml:p[@class='li > stitem > bullets'])][1])[last()])"/> > <xsl:key name="unorderedlists-indented" > match="xhtml:p[@class='listitemindented']" > use="generate-id((..|preceding-sibling::*[not(self::xhtml:p[@class='li > stitem > 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>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Nested lists, Heiko Niemann | Thread | [xsl] xsl 2.0?, Paul Tyson |
[xsl] xsl 2.0?, Paul Tyson | Date | Re: [xsl] xsl 2.0?, Liam R E Quin |
Month |