|
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 |