- From: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>
- Date: Wed, 13 Oct 2004 15:02:55 -0500 (CDT)
- To: www-xsl-fo@w3.org
In regard to: Re: node after current node in xsl:for-each with xsl:sort...: > Actually it's a bit tricky in pure xslt 1 to sort and then access the > sorted list at the same time, as the sorted list information goes to the > result tree where by design you can't really get it back. > > If you can use your processor's node-set extension (if it has one) first > sort the input into a temporary variable then process every other item > in this sorted list, and access the next item by > following-sibling::*[1] > if xx:node-set() isn't available, ask again:-) [For the benefit of the list archives] With David's help and some additional info from the web, especially archived posts to the xsl-list by Michael Kay http://www.mail-archive.com/xslt@p2p.wrox.com/msg06645.html and Jeni Tennison http://www.xslt.com/html/xsl-list/2002-01/msg00472.html http://www.jenitennison.com/xslt/index.html (the grouping links) I eventually arrived at: <fo:table-body> <xsl:variable name="sorted_accounts"> <xsl:for-each select="/request/account"> <xsl:sort select="id" /> <xsl:copy-of select="." /> </xsl:for-each> </xsl:variable> <xsl:for-each select="exslt:node-set($sorted_accounts)/account"> <!-- output a table row if position() mod 2 = 1 --> <xsl:if test="position() mod 2 = 1"> <xsl:value-of select="$newline" /> <fo:table-row keep-together="always"> <xsl:value-of select="$newline" /> <xsl:apply-templates select="." mode="cutsheet" /> <xsl:apply-templates select="following-sibling::*[1]" mode="cutsheet" /> </fo:table-row> <xsl:value-of select="$newline" /> </xsl:if> </xsl:for-each> </fo:table-body> Along with an "account" template (two, with two different modes for the two types of account cells I need to output on different parts of the form) for each cell in the table, this is working perfectly. Two notes for future archive searchers: - it would seem like the exslt:node-set used in the xsl:for-each should be just <xsl:for-each select="exslt:node-set($sorted_accounts)"> Since I'm already iterating over /request/account when I create the variable. That's not the case, though. The node-set($sorted_accounts) essentially "re-roots" a copy of everything that was included in the xsl:variable. - This has implications for the xsl:apply-templates calls, because they're being called with this "re-rooted" document, so if the templates want to access something like <xsl:value-of select="/request/foo/bar" /> that won't work because the template is being applied to this "re-rooted" document, which doesn't have the same document root as the overall document. The trick that's used to get around this is to make a variable that "points to" your main document root, via something like <xsl:variable name="maindoc_root" select="/" /> near the top of your stylesheet, and then use <xsl:value-of select="$maindoc_root/request/foo/bar" /> within the template calls that need to access nodes outside the "re-rooted" nodes they've been called with. My understanding of these last two points is still hazy so my explanation is probably poor, but I hope this helps someone else in the future. Thanks all, especially David! Tim -- Tim Mooney mooney@dogbert.cc.ndsu.NoDak.edu Information Technology Services (701) 231-1076 (Voice) Room 242-J6, IACC Building (701) 231-8541 (Fax) North Dakota State University, Fargo, ND 58105-5164
Received on Wednesday, 13 October 2004 20:02:59 UTC