Subject: Re: [xsl] Showing unique rows at multiple levels From: Glen Mazza <grm7790@xxxxxxxxxxx> Date: Thu, 05 Oct 2006 12:10:27 -0400 |
> Hi, > > Your expression "//book[(bookshelf = > $bookshelfVar)]/author[not(.=preceding::author)]" is too strict (the > predicate too tolerant). You need to limit the preceding::author part to > match only authors that are on the same bookshelf. Similar thing for the > publisher. :-)
> > Besides, I would recommend trying to use keys and grouping techniques > like the Muenchian method. Something like: >
Regards, Glen
Actually, I meant something like:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="bookshelves" match="bookshelf" use="." /> <xsl:key name="authors" match="author" use="concat(../bookshelf, '-', .)" /> <xsl:key name="publishers" match="publisher" use="concat(../bookshelf, '-', ../author, '-', .)" />
<xsl:template match="books"> <xsl:apply-templates select="book/bookshelf"> <xsl:sort select="."/> </xsl:apply-templates> </xsl:template>
<xsl:template match="bookshelf">
<xsl:if test="generate-id(.) = generate-id(key('bookshelves',
.)[1])">
<xsl:variable name="bookshelfVar" select="."/>
<xsl:variable name="authorVar" select="../author"/>
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:apply-templates select="/books/book[(bookshelf =
$bookshelfVar)]/author">
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
<xsl:template match="author"> <xsl:if test="generate-id(.) = generate-id(key('authors', concat(../bookshelf, '-', .))[1])"> <xsl:variable name="bookshelfVar" select="../bookshelf"/> <xsl:variable name="authorVar" select="."/>
<xsl:text> --</xsl:text> <xsl:value-of select="."/>
<xsl:apply-templates select="/books/book[(bookshelf = $bookshelfVar) and (author = $authorVar)]/publisher"> <xsl:sort select="."/> </xsl:apply-templates> </xsl:if> </xsl:template>
<xsl:template match="publisher"> <xsl:if test="generate-id(.) = generate-id(key('publishers', concat(../bookshelf, '-', ../author, '-', .))[1])"> <xsl:text> ----</xsl:text> <xsl:value-of select="."/> </xsl:if> </xsl:template>
</xsl:stylesheet>
It replaces // by explicit paths and preceding axis by keyed indexes..
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.
Van: Geert Josten [mailto:geert.josten@xxxxxxxxxxx] Verzonden: donderdag 5 oktober 2006 8:13
Aan: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Onderwerp: RE: [xsl] Showing unique rows at multiple levels
Hi,
Your expression "//book[(bookshelf =
$bookshelfVar)]/author[not(.=preceding::author)]" is too strict (the predicate too tolerant). You need to limit the preceding::author part to match only authors that are on the same bookshelf. Similar thing for the publisher. :-)
Besides, I would recommend trying to use keys and grouping techniques like the Muenchian method. Something like:
(at top-level)
<xsl:key name="bookshelfs" match="bookshelf" use="." /> <xsl:key name="authors" match="author" use="concat(../bookshelf, '-', .)" />
(inside bookshelf template)
<xsl:for-each select="key('bookshelfs', .)[1]"> ... </xsl:for-each>
(inside author template)
<xsl:for-each select="key('authors', concat(../bookshelf, '-', .)[1]"> ... </xsl:for-each>
Probably a lot quicker if your data file becomes larger. Using // is usually very expensive in that case..
Kind regards, Geert
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Showing unique rows at mu, Geert Josten | Thread | [xsl] Nested Muenchian Grouping, Minervini, Chris |
Re: [xsl] Nested Muenchian Grouping, Mukul Gandhi | Date | [xsl] Retrieve part of node, Guy |
Month |