This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: HTML: unordered list within unordered list
- From: "Joerg Heinicke" <joerg dot heinicke at gmx dot de>
- To: <xsl-list at lists dot mulberrytech dot com>
- Date: Sun, 28 Apr 2002 13:56:43 +0200
- Subject: Re: [xsl] HTML: unordered list within unordered list
- References: <20020428004731.44251.qmail@web11304.mail.yahoo.com>
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hello Rich,
again unstructured XML, again unordered list ... deja vu?
The problem with your code are the <xsl:call-template/>. In my eyes they are
not good, especially for such tasks. Maybe it's impossible with
<xsl:call-template/>, but I didn't try. I think you should have a look at
<xsl:apply-templates/> and <xsl:template match=""/>. It's important to
understand the template driven approach of XSLT.
As in my last mail an half hour ago I use again <xsl:key/>. This time the
Muenchian Method for grouping elements as described on Jeni's page at
http://www.jenitennison.com/xslt/index.xml (or many examples in the archives
of the list).
At first I group the <Property>s by their number (without a or b or ...).
For this everything else is translated to ''. You could write translate(.,
'abcdef...', '') too, but the version with first translation of '1234...' to
nothing should be shorter.
All <Property>s are now in a group with their number as key.
<xsl:key name="items" match="Property" use="translate(., translate(.,
'1234567890', ''), '')"/>
<xsl:template match="root">
<ul>
<!-- The Muenchian Method itself. The first element of every group is
selected. -->
<xsl:apply-templates select="
Property[
count( . |
key('items',
translate(., translate(., '1234567890', ''), '')
)[1]
) = 1
]
"/>
</ul>
</xsl:template>
<xsl:template match="Property">
<!-- create the number -->
<xsl:variable name="item-number" select="translate(., translate(.,
'1234567890', ''), '')"/>
<!-- if you need type="circle" add it here -->
<li><xsl:value-of select="."/></li>
<!-- if there are more <Property>s with the same number and if it's not
already the second level -->
<xsl:if test="count(key('items', $item-number)) > 1
and not(normalize-space(substring-after(., $item-number)))">
<ul>
<!-- select all <Property>s with this number except level 1 (the first
<Property> with this number) -->
<xsl:apply-templates select="key('items',
$item-number)[position()!=1]"/>
</ul>
</xsl:if>
</xsl:template>
Regards,
Joerg
----- Original Message -----
From: "Rich Garcia" <rchgrca@yahoo.com>
> Folks,
>
> I'm trying to generate the following HTML output:
> <ul>
> <li>item1</li>
> <li>item2</li>
> <li>
> <ul>
> <li type="circle">item2a</li>
> <li type="circle">item2b</li>
> <ul>
> </li>
> <li>item3</li>
> <li>item4</li>
> </ul>
>
> My xml looks like:
> <Property type="bullet">item1</Property>
> <Property type="bullet">item2</Property>
> <Property type="bullet"
> icon="circle">item2a</Property>
> <Property type="bullet"
> icon="circle">item2b</Property>
> <Property type="bullet">item3</Property>
> <Property type="bullet">item4</Property>
>
> My templates look like:
>
> <xsl:call-template name="showbullets"/>
>
> <xsl:template name="showbullets">
> <xsl:if test="Property/@type = 'bullet'">
> <xsl:call-template name="ul"/>
> </xsl:if>
> </xsl:template>
>
> <!-- creates <ul> -->
> <xsl:template name="ul">
> <ul><xsl:call-template name="li"/></ul>
> </xsl:template>
>
> <!-- creates unorder list bullets <li> -->
> <xsl:template name="li">
> <xsl:for-each select="Property">
> <li>
> <xsl:if test="@icon='circle'">
> <xsl:attribute
> name="type">circle</xsl:attribute>
> </xsl:if>
> <xsl:value-of select="@name"/><xsl:value-of
> select="."/><xsl:text> </xsl:text><xsl:value-of
> select="@yeargraduated"/>
> </li>
> </xsl:for-each>
> </xsl:template>
>
> Any suggestions? I'm drawing a blank...
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list