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

RE: Showing unique rows at multiple levels

Subject: RE: Showing unique rows at multiple levels
From: "Geert Josten" <geert.josten@xxxxxxxxxxx>
Date: Thu, 5 Oct 2006 08:12:35 +0200
download b6 mu
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:  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

PURCHASE STYLUS STUDIO ONLINE TODAY!

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

Buy Stylus Studio Now

Cast Your Vote

We need your help – Vote for DataDirect XML Products!

  • Best SOA or XML site

Winners and finalists announced at SOA World Conference in November.

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-2007 All Rights Reserved.