[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: Constructing multi-level lists - any better than

Subject: RE: Constructing multi-level lists - any better than this?
From: "Geert Josten" <geert.josten@xxxxxxxxxxx>
Date: Sat, 15 Sep 2007 19:07:14 +0200
RE:  Constructing multi-level lists - any better than
Hi,

I would have done something like this (pseudo-code):

<template match="p">
	<copy />
</template>

<template match="l1|l2">
	<if test="preceding-sibling::*[1][self::p]">
		<ul>
			<apply-templates select="." mode="level1" />
		</ul>
	</if>
</template>

<template match="*" mode="level1">
	<!-- terminate continuation if not l1 or l2 -->
</template>

<template match="l1" mode="level1">
	<copy />
	<apply-templates select="following-sibling::*[1]" mode="level1" />
</template>

<template match="l2" mode="level1">
	<if test="preceding-sibling::*[1][self::p or self::l1]">
		<ul>
			<apply-templates select="." mode="level2" />
		</ul>
	</if>
	<apply-templates select="following-sibling::*[1]" mode="level1" />
</template>

<template match="*" mode="level2">
	<!-- terminate continuation if not l2 -->
</template>

<template match="l2" mode="level2">
	<copy />
	<apply-templates select="following-sibling::*[1]" mode="level2" />
</template>

But it is limited by recursion depth. On the other hand, it doesn't require
XSLT 2.0.

Kind regards,
Geert

>


Drs. G.P.H. Josten
Consultant



Daidalos BV
Source of Innovation
Hoekeindsehof 1-4
2665  JZ  Bleiswijk
Tel.: +31 (0) 10 850 1200
Fax: +31 (0) 10 850 1199
www.daidalos.nl
KvK 27164984


De informatie - verzonden in of met dit emailbericht - is afkomstig van
Daidalos BV en is uitsluitend bestemd voor de geadresseerde. Indien u dit
bericht onbedoeld hebt ontvangen, verzoeken wij u het te verwijderen. Aan dit
bericht kunnen geen rechten worden ontleend.


> From: Michael M|ller-Hillebrand [mailto:mmh@xxxxxxxxxxxxx]
> Sent: zaterdag 15 september 2007 18:44
> To: XSL-List
> Subject:  Constructing multi-level lists - any better than this?
>
> Hello,
>
> I have a working stylesheet, but it uses modes when I think
> it could be a bit slimmer and maybe more flexible.
>
> The task is to create list containers (<ul>) around list
> elements in a flat element tree. I tried to follow Jeni
> Tennison's advice for constructing hierarchies
> <http://jenitennison.com/xslt/hierarchies-
> out.xml> and also evaluated xsl:for-each-group, but the
> latter seems not to work very well for a stylesheet in push
> mode (no changes to the element order).
>
> To correctly group the <li1>s and <li2>s (even in the third
> case) in this example I successfully used the XSL below. I
> found no good enough example in the FAQs, so I dare to ask,
> whether there is a more elegant solution. (I simplified the
> case, in reality there are multiple elements that are either
> level 1 or level 2 list elements, and I do not use
> starts-with() to detect element names.)
>
> Any advice is greatly appreciated!
>
> - Michael M|ller-Hillebrand
>
> <?xml version="1.0" encoding="UTF-8"?>
> <levels>
> <p/>
> <li1>1</li1>
> <li1>2</li1>
> <li1>3</li1>
> <li1>4</li1>
> <p/>
> <li1>5</li1>
> <li1>6</li1>
> <li2>7.1</li2>
> <li2>7.2</li2>
> <p/>
> <li2>8.1</li2>
> <li2>8.2</li2>
> <li1>9</li1>
> <li1>10</li1>
> <p/>
> </levels>
>
> ---------
>
> <xsl:stylesheet version="2.0"
>                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:strip-space elements="*"/>
> <xsl:output method="xml" indent="yes" />
>
> <!-- Root element -->
> <xsl:template match="levels">
>    <xsl:copy>
>      <xsl:apply-templates />
>    </xsl:copy>
> </xsl:template>
>
> <!-- Keys to identify list elements after first element -->
> <xsl:key name="list12-other"
>    match="*[self::*[starts-with(name(), 'li')]
>      and preceding-sibling::*[1][starts-with(name(), 'li')]]"
>    use="generate-id(
>      preceding-sibling::*[
>        starts-with(name(), 'li')
>        and not(preceding-sibling::*[1][starts-with(name(), 'li')])
>      ][1])" />
>
> <xsl:key name="list2-other"
>    match="li2[preceding-sibling::*[1][self::li2]]"
>    use="generate-id(
>      preceding-sibling::li2[
>        not(preceding-sibling::*[1][self::li2])
>      ][1])" />
>
> <!-- List 1 Container-->
> <xsl:template match="*[starts-with(name(), 'li')
>    and not(preceding-sibling::*[1][starts-with(name(), 'li')])]"
> priority="1">
>    <ul level="1">
>      <xsl:apply-templates mode="list1"
>        select=". | key('list12-other', generate-id())" />
>    </ul>
> </xsl:template>
> <!-- List 1 elements -->
> <xsl:template match="li1" mode="list1">
>    <li tag="{name()}" pos="{position()}">
>      <xsl:apply-templates />
>    </li>
> </xsl:template>
>
> <!-- or List 2 Container-->
> <xsl:template match="li2[not(preceding-sibling::*[1][self::li2])]"
>    mode="list1" priority="1">
>    <ul level="2">
>      <xsl:apply-templates mode="list2"
>        select=". | key('list2-other', generate-id())" />
>    </ul>
> </xsl:template>
> <!-- List 2 elements -->
> <xsl:template match="li2" mode="list2">
>    <li tag="{name()}" pos="{position()}">
>      <xsl:apply-templates />
>    </li>
> </xsl:template>
>
> <!-- skip list elements when matched outside list -->
> <xsl:template match="li2" mode="list1"/> <xsl:template
> match="*[starts-with(name(), 'li')]"/>
>
> <!-- all other nodes -->
> <xsl:template match="node()">
>    <xsl:copy>
>      <xsl:apply-templates />
>    </xsl:copy>
> </xsl:template>
>
> </xsl:stylesheet>

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.