This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: breaking sorted material into subsections
- To: xsl-list at mulberrytech dot com
- Subject: RE: breaking sorted material into subsections
- From: Don Bruey <dbruey at CreativeSolutions dot com>
- Date: Mon, 18 Sep 2000 13:06:23 -0400
- Reply-To: xsl-list at mulberrytech dot com
Oliver,
Thanks for reading carefully - I cut and pasted from the wrong XML file. I
have been using this list to find examples of problems to solve and trying
to solve them to teach myself XSL, I goofed on this one. My test input was
sorted in document order and I changed it before I pasted into my reply.
Don
DaveP: better take the "bad" XSL out of the FAQ
> -----Original Message-----
> From: Oliver Becker [mailto:obecker@informatik.hu-berlin.de]
> Sent: Monday, September 18, 2000 11:02 AM
> To: xsl-list@mulberrytech.com
> Subject: RE: breaking sorted material into subsections
>
>
> Hi Don,
>
> > Assuming XML looks something like this (@location left out
> because question
> > didn't pertain to parent's @location href):
> >
> >
> > <IndexEntryData>
> > <index entry = "Ca">Index1</index>
> > <index entry = "Aaaa">Index1</index>
> > <index entry = "Az">Index1</index>
> > <index entry = "Bz">Index1</index>
> > <index entry = "Abb">Index1</index>
> > <index entry = "Ba">Index1</index>
> > </IndexEntryData>
> >
> > This works in MSXML3 and SAXON
>
> Do you have a different version of Saxon from mine (which is
> Saxon 5.4.1)?
>
> > <xsl:template match="/">
> > <xsl:for-each select="//index">
> > <xsl:sort select="@entry"/>
> >
> > <!-- if first character of @entry attrib of first preceding -->
> > <!-- node is not equal to the context's @entry attrib -->
> > <!-- it's a "break" on first character of @entry -->
> > <!-- this works because we're already sorted by @entry -->
> >
> > <xsl:if test ="substring(preceding::*[1]/@entry, 1, 1) !=
> > substring(@entry, 1, 1)">
>
> All axes apply to the nodes in the document, not to a
> selected node-set.
> That means, your test checks if the entry attribute of the preceding
> element in the *document* starts with a different letter.
>
> > <H2><xsl:value-of select="substring(@entry, 1, 1)" /></H2>
> > </xsl:if>
> >
> > <p>
> > <a href="{../@location}">
> > <xsl:value-of select="@entry"/>
> > </a>
> > </p>
> > </xsl:for-each>
> > </xsl:template>
>
> As a result Saxon outputs (newlines added)
> <H2>A</H2>
> <p><a href="">Aaaa</a></p>
> <H2>A</H2>
> <p><a href="">Abb</a></p>
> <p><a href="">Az</a></p>
> <H2>B</H2>
> <p><a href="">Ba</a></p>
> <H2>B</H2>
> <p><a href="">Bz</a></p>
> <H2>C</H2>
> <p><a href="">Ca</a></p>
>
> i.e. two A headers and two B headers.
>
> In fact it's a grouping problem: gather all indizes starting with the
> same letter.
> Always a good reading for this kind of problems is
> http://www.jenitennison.com/xslt/grouping/muenchian.html
>
> Adapted to Eric's problem I get
>
> <xsl:key name="letters" match="index" use="substring(@entry,1,1)" />
> <xsl:template match="IndexEntryData">
> <xsl:for-each
> select="index[count(. | key('letters',
> substring(@entry,1,1))[1]) = 1]">
> <xsl:sort select="@entry" />
> <xsl:variable name="initial" select="substring(@entry,1,1)" />
> <h2> <xsl:value-of select="$initial" /> </h2>
> <xsl:for-each select="key('letters', $initial)">
> <xsl:sort select="@entry" />
> <p> <xsl:value-of select="@entry" /> </p>
> </xsl:for-each>
> </xsl:for-each>
> </xsl:template>
>
> Cheers,
> Oliver
>
>
> /-------------------------------------------------------------------\
> | ob|do Dipl.Inf. Oliver Becker |
> | --+-- E-Mail: obecker@informatik.hu-berlin.de |
> | op|qo WWW: http://www.informatik.hu-berlin.de/~obecker |
> \-------------------------------------------------------------------/
>
>
> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list