RE: [xsl] XSL - using for-each with sort - can't access previous sorted nod e

Subject: RE: [xsl] XSL - using for-each with sort - can't access previous sorted nod e
From: Rick Taylor <taylor@xxxxxxxx>
Date: Wed, 26 Nov 2003 11:51:17 -0700
Jeff,

If you are needing this to be transformed in IE then you can use the msxsl:node-set extension. The following is shows one way (not necessarily the best) to use it.

Here is your XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test.xsl" type="text/xsl"?>
<quiz>
    <question id="1" page="4"/>
    <question id="2" page="6"/>
    <question id="3" page="1"/>
    <question id="4" page="18"/>
    <question id="5" page="7"/>
    <question id="6" page="5"/>
</quiz>

and here is your xsl (named test.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                version="1.0">

<xsl:output method="html" indent="yes" encoding="UTF-8"/>

    <xsl:variable name="questions">
     <xsl:for-each select="//quiz/question">
      <xsl:sort select="@page" data-type="number"/>
       <xsl:copy-of select="."/>
     </xsl:for-each>
    </xsl:variable>

<xsl:template match="/">
<html>
<body>
<xsl:for-each select="msxsl:node-set($questions)/question">
CurrentID=<xsl:value-of select="@id"/>,
<b>
<xsl:if test="preceding-sibling::question[1]">
PreviousID=<xsl:value-of select="preceding-sibling::question[1]/@id"/>
</xsl:if>
</b>
<br/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>


Note that this is not a two-pass process. Two passes would entail transforming the xml first to get the sorted nodes (outputted to another xml document), and then transforming that result to display it as html.

rick

At 07:01 PM 11/25/2003 -0500, you wrote:
Wendell / Rick,

Thanks very much for the replies. Both your replies represent more than I've
been able to get in two days of researching this :) I appreciate it.

Wendell, I'm not at all familiar with the node-et extension. I'm currently
using Internet Explorer's built-in XSL processor to transform my XML docs.
I'm not sure if IE's processor supports node-set extension. Would it be too
much trouble to ask either of you for an example of a two-pass process? I'm
not asking you to write the whole thing for me :) Just an example. I've
never written an XSLT doc that did two passes (never came across a problem
like this before... where it necessitated it).

Many thanks,

Jeff

-----Original Message-----
From: Wendell Piez [mailto:wapiez@xxxxxxxxxxxxxxxx]
Sent: Tuesday, November 25, 2003 6:30 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] XSL - using for-each with sort - can't access
previous sorted nod e


Jeff,


Rick's tip is a good one although it doesn't address your actual problem.

The problem you posed is rather tricky, since XSLT 1.0 doesn't have ready
access to its own results. The cleanest solution would therefore be to
process your list in two passes, the first to sort, the second to format.
The second pass then has access to the sorted order. This can be done
either with two stylesheets, or with one stylesheet and your processor's
node-set() extension function (most have one).

If you really want to do it in one pass, it's not impossible, but it won't
be pretty.

Please advise if these hints aren't enough and you'd like more specifics on
any of the options I've mentioned. I'd probably use the node-set()
extension function as the best balance of simple and efficient, if I could
be sure the function would be available when the stylesheet is run. (In
XSLT 2.0 you'll be able to do the same thing transparently.)

Cheers,
Wendell

At 05:16 PM 11/25/2003, Rick wrote:
>Jeff,
>
>Make sure that when you sort you specify the data-type
><xsl:sort select="@page" data-type="number"/>
>or the 18 will come after the 1 and before the 2.
>
>rick
>
>At 04:45 PM 11/25/2003 -0500, you wrote:
>>Hi all... just joined this list. Greetings :)
>>
>>I was wondering if someone might have an answer for me on this...
>>
>>Here's sample XML:
>>
>><quiz>
>>    <question id="1" page="4"/>
>>    <question id="2" page="6"/>
>>    <question id="3" page="1"/>
>>    <question id="4" page="18"/>
>>    <question id="5" page="7"/>
>>    <question id="6" page="5"/>
>></quiz>
>>
>>In my XSLT, I want to sort by page. So I have:
>>
>><xsl:for-each select="question">
>><xsl:sort select="@page"/>
>>
>>Now - as I am doing things to each question during the for-each, I want to
>>be able to access the "id" attribute in the question outputted JUST PRIOR
to
>>the one currently being outputted. I can't seem to be able to do this.
I've
>>tried using position() and <xsl:number> and combinations of the two, and
>>have been unsuccessful. Could anyone give me some advice?
>
>
>======================================================================
>Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
>Mulberry Technologies, Inc.                http://www.mulberrytech.com
>17 West Jefferson Street                    Direct Phone: 301/315-9635
>Suite 207                                          Phone: 301/315-9631
>Rockville, MD  20850                                 Fax: 301/315-8285
>----------------------------------------------------------------------
>   Mulberry Technologies: A Consultancy Specializing in SGML and XML
>======================================================================


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



**************************************************************************** This email may contain confidential material. If you were not an intended recipient, please notify the sender and delete all copies. We may monitor email to and from our network.

****************************************************************************



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list

Rick Taylor XML Developer PPDM Association


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread