Subject: RE: [xsl] Showing unique rows at multiple levels From: "Geert Josten" <geert.josten@xxxxxxxxxxx> Date: Thu, 5 Oct 2006 08:12:35 +0200 |
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 > 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: Glen Mazza [mailto:grm7790@xxxxxxxxxxx] > Verzonden: woensdag 4 oktober 2006 20:08 > Aan: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Onderwerp: [xsl] Showing unique rows at multiple levels > > Hello, for this input XML: > > <books> > <book> > <title>T1</title> > <author>A5</author> > <publisher>P7</publisher> > <bookshelf>B4</bookshelf> > </book> > <book> > <title>T2</title> > <author>A6</author> > <publisher>P8</publisher> > <bookshelf>B4</bookshelf> > </book> > <book> > <title>T4</title> > <author>A5</author> > <publisher>P7</publisher> > <bookshelf>B6</bookshelf> > </book> > <book> > <title>T3</title> > <author>A5</author> > <publisher>P7</publisher> > <bookshelf>B4</bookshelf> > </book> > </books> > > I would like an alphabetically sorted list of each unique > bookshelf, and under each bookshelf, each unique author of at > least one book on that shelf, and under each author, each > unique publisher of at least one book by that author (on that shelf). > > I.e., for the above, the following is desired: > > B4 > --A5 (show just once even though 2 books of A5) > ----P7 (show just once even though 2 books of P7 under A5 on B4) > --A6 > ----P8 > B6 > --A5 > ----P7 > > Unfortunately, I am getting this: > > B4 > --A5 > ----P7 > --A6 > ----P8 > B6 > > where A5 and P7 are erroneously missing under shelf B6, because A5 and > P7 already happen to exist under shelf B4. (In my sample > data, if I rename A5 to say A15 and P7 to P17, i.e., nodes > that don't exist elsewhere, these nodes then *will* appear under B6.) > > Something is wrong with my filtering--I only want an author > to be suppressed if it is already listed for the *same* > shelf, and likewise with publishers under the same author > (under the same shelf). > > Here is my XSLT: > > <xsl:stylesheet version="1.0" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > <xsl:template match="books"> > <xsl:for-each select="//bookshelf[not(.=preceding::bookshelf)]"> > <xsl:sort select="."/> > <xsl:apply-templates select='.'/> > </xsl:for-each> > </xsl:template> > > <xsl:template match="bookshelf"> > <xsl:variable name="bookshelfVar" select="."/> > <xsl:variable name="authorVar" select="../author"/> > <xsl:value-of select="."/> > <xsl:for-each select="//book[(bookshelf = > $bookshelfVar)]/author[not(.=preceding::author)]"> > <xsl:sort select="."/> > <xsl:apply-templates select='.'/> > </xsl:for-each> > </xsl:template> > > <xsl:template match="author"> > <xsl:variable name="bookshelfVar" select="../bookshelf"/> > <xsl:variable name="authorVar" select="."/> > --<xsl:value-of select="."/> > <xsl:for-each select="//book[(bookshelf = $bookshelfVar) > and (author = $authorVar)]/publisher[not(.=preceding::publisher)]"> > <xsl:sort select="."/> > <xsl:apply-templates select='.'/> > </xsl:for-each> > </xsl:template> > > <xsl:template match="publisher"> > ----<xsl:value-of select="."/> > </xsl:template> > > </xsl:stylesheet> > > Can anyone see what I am doing wrong? Any help would be appreciated. > > Thanks, > Glen
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Showing unique rows at multip, Glen Mazza | Thread | RE: [xsl] Showing unique rows at mu, Geert Josten |
Re: [xsl] Count occurence and add t, Arulraj | Date | RE: [xsl] Showing unique rows at mu, Geert Josten |
Month |