Subject: RE: breaking sorted material into subsections From: Oliver Becker <obecker@xxxxxxxxxxxxxxxxxxxxxxx> Date: Mon, 18 Sep 2000 17:01:50 +0200 (MET DST) |
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@xxxxxxxxxxxxxxxxxxxxxxx | | op|qo WWW: http://www.informatik.hu-berlin.de/~obecker | \-------------------------------------------------------------------/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: breaking sorted material into s, Don Bruey | Thread | Re: breaking sorted material into s, Nick Browne |
Re: Can XSL/XSLT draw nodes/applets, Wendell Piez | Date | RE: simple grouping question, Ben Robb |
Month |