Subject: Re: [xsl] forum threads sorting From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Tue, 26 Feb 2002 17:08:49 +0000 |
Hi Oleg, > I can sort by root/aaa dates, but I can't consider descendant > messages > > <xsl:sort select="translate(@vl, '-, ','')" /> As I understand it, the difficulty is that, given an aaa element, you can't tell which of the many descendants has the latest date, so that you can sort on that. The easiest way to approach this, I think, is to make it a two-step process. In the first step, create a copy of the source document, and for each aaa element add a 'lastModified' attribute that gives the latest date of their ancestor aaa elements, as follows: <xsl:template match="aaa" mode="addLastModifiedAttribute"> <aaa> <xsl:copy-of select="@*" /> <xsl:attribute name="lastModified"> <xsl:for-each select="descendant-or-self::aaa"> <xsl:sort select="@vl" order="descending" /> <xsl:if test="position() = 1"> <xsl:value-of select="@vl" /> </xsl:if> </xsl:for-each> </xsl:attribute> <xsl:apply-templates select="*" /> </aaa> </xsl:template> You can store the result of this first step in a variable, through something like: <xsl:variable name="aaaWithLastModified-rtf"> <xsl:apply-templates select="aaa" mode="addLastModified" /> </xsl:variable> Then you can convert this variable into a node set using a node-set extension function (I know it's not pure XSLT, but it's close enough!), and process the aaa elements in the order of their lastModified attribute: <xsl:apply-templates select="exsl:node-set($aaaWithLastModified-rtf) /aaa"> <xsl:sort select="@lastModified" order="descending" /> </xsl:apply-templates> If you don't want to use an extension node-set function, then it's a bit more complicated. I'd approach it with a recursive template that accepts a bunch of aaa elements, locates the one with the latest date, locates its ancestor amongst the aaa elements passed as the parameter, applies templates to that ancestor, and then calls itself on a new set of aaa elements that doesn't include that ancestor or any of its descendants, as follows: <xsl:template name="latestMessage"> <xsl:param name="messages" select=".//aaa" /> <xsl:for-each select="$messages"> <xsl:sort select="@vl" /> <xsl:if test="position() = 1"> <xsl:variable name="latest" select="." /> <xsl:variable name="ancestor" select="$latest/ancestor::aaa[count(.|$messages) = count($messages)]" /> <xsl:apply-templates select="$ancestor" /> <xsl:variable name="remainder" select="$messages[not(ancestor-or-self::aaa [generate-id() = generate-id($ancestor)])]" /> <xsl:if test="$remainder"> <xsl:call-template name="latestMessage"> <xsl:with-param name="messages" select="$remainder" /> </xsl:call-templates> </xsl:if> </xsl:if> </xsl:for-each> </xsl:template> This is likely to be very time-consuming. You could improve the speed by using another method to find the latest message, rather than the sort-and-select-the-first method. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] forum threads sorting, Oleg Tkachenko | Thread | RE: [xsl] forum threads sorting, McNally, David |
Re: [xsl] forum threads sorting, Oleg Tkachenko | Date | Re: [xsl] XSL Formatting Problem, Jeni Tennison |
Month |