Subject: RE: breaking sorted material into subsections From: Don Bruey <dbruey@xxxxxxxxxxxxxxxxxxxxx> Date: Mon, 18 Sep 2000 13:06:23 -0400 |
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@xxxxxxxxxxxxxxxxxxxxxxx] > Sent: Monday, September 18, 2000 11:02 AM > To: xsl-list@xxxxxxxxxxxxxxxx > 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@xxxxxxxxxxxxxxxxxxxxxxx | > | 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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: breaking sorted material into s, Nick Browne | Thread | RE: breaking sorted material into s, Eric Taylor |
XML+XSL to HTML strategies advice n, Dylan Parker | Date | Re: simple grouping question, Les Howard |
Month |