[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] sorting question


Subject: RE: [xsl] sorting question
From: "Diamond, Jason" <Jason.Diamond@xxxxxxx>
Date: Wed, 7 Mar 2001 19:00:31 -0600

That certainly complicates things. But it is still possible using XSLT
1.0--although it's certainly not efficient.

<xsl:transform version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

  <xsl:template match="ALPHABET">
    <xsl:for-each select="LETTER">
      <xsl:sort select="."/>
      <xsl:if test="position() mod 2 = 1">
        <tr>
          <td>
            <xsl:value-of select="."/>
          </td>
          <xsl:variable name="next" select="position() + 1"/>
          <xsl:for-each select="../LETTER">
            <xsl:sort select="."/>
            <xsl:if test="position() = $next">
              <td>
                <xsl:value-of select="."/>
              </td>
            </xsl:if>
          </xsl:for-each>
        </tr>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:transform>

We're basically iterating over the sorted list and then grabbing the next
element in the sorted list by iterating over the same list _again_ but only
outputting when we're at the position we want. Would this be O(n*n!)?

What would be really nice would be a following-node axis (along with a
corresponding preceding-node). This would help select the following or
preceding nodes in the current node list (as constructed by
<xsl:apply-templates> or <xsl:for-each>). This would obviously be specific
to XSLT since XPath doesn't have any notion of a current node list. This use
case seems like a good justification for those axis specifiers, though. 

Does anybody know if there is anything planned for XSLT 2.0 that might make
this easier?

Jason.

-----Original Message-----
From: Oliver Rutherfurd [mailto:fruhstuck@xxxxxxxxxxxxxx]
Sent: Wednesday, March 07, 2001 4:19 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] sorting question


Thanks Jason!

However, if I wanted instead of (x,y) to output
'<tr><td>x</td><td>y</td></tr>' how would I go about that?  As the xsl below
isn't valid xml because of the unbalanced '<tr>' & '</tr>'?

<xsl:for-each select="LETTER">
  <xsl:sort select="."/>
   <xsl:choose>
    <xsl:when test="position() mod 2 = 1">
      <tr>
      <td><xsl:value-of select="."/></td>
    </xsl:when>
    <xsl:otherwise>
      <td><xsl:value-of select="."/></td>
     </tr>
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each>

Is there any way I can do that?

Thanks,
-Ollie

> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx]On Behalf Of Diamond,
> Jason
> Sent: Wednesday, March 07, 2001 6:14 PM
> To: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx'
> Subject: RE: [xsl] sorting question
>
>
> Since it's not possible to sort node-sets when selecting them (with
> <xsl:variable>, for example), the positions of the nodes in your $letters
> variable are different than the positions of the nodes as you
> loop over them
> (because of the <xsl:sort> element).
>
> So, if you just loop over the sorted nodes and keep track of your position
> in that list, you can control when you output the '(' as opposed
> to the ')'.
>
> The following transform seems to produce the output that you want
> using both
> MSXML3 and SAXON 6.2:
>
> <xsl:transform version="1.0"
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> >
>   <xsl:output method="text" encoding="UTF-8"/>
>
>   <xsl:template match="ALPHABET">
>     <xsl:for-each select="LETTER">
>       <xsl:sort select="."/>
>       <xsl:choose>
>         <xsl:when test="position() mod 2 = 1">
>           <xsl:text>(</xsl:text>
>           <xsl:value-of select="."/>
>         </xsl:when>
>         <xsl:otherwise>
>           <xsl:text>,</xsl:text>
>           <xsl:value-of select="."/>
>           <xsl:text>)</xsl:text>
>         </xsl:otherwise>
>       </xsl:choose>
>     </xsl:for-each>
>   </xsl:template>
>
> </xsl:transform>
>
> You'll be left with an unclosed pair if you happen to have an odd
> number of
> nodes but you could check for that by testing the count of the
> LETTER nodes
> and outputting a closing a ')' if necessary.
>
> Hope this helps,
> Jason.
>
> -----Original Message-----
> From: Oliver Rutherfurd [mailto:fruhstuck@xxxxxxxxxxxxxx]
> Sent: Wednesday, March 07, 2001 11:35 AM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] sorting question
>
>
> Hello,
>
> I'm trying to transform a list of elements into a sorted set of pairs, and
> haven't
> been able to determine how to get the 'next' sorted element
> relative to the
> current
> position.  As I couldn't get it to work with 'real' data, I
> simplified it to
> make it easier to play with (and explain).  Below is a little xml and the
> xsl
> I'm trying to use.  Any tips or hints would be great!
>
> here's a little data:
>
> <ALPHABET>
>  <LETTER>a</LETTER>
>  <LETTER>d</LETTER>
>  <LETTER>b</LETTER>
>  <LETTER>c</LETTER>
> </ALPHABET>
>
> I would like results like:
>
> (a,b)(c,d)
>
> The following selects the second element based on it's position
> in nodeset,
> not the sorted nodeset.
>
> <xsl:variable name="letters" select="/ALPHABET/LETTER" />
>
> <xsl:for-each select="$letters">
>  <xsl:sort select="." />
>  <xsl:if test="(position() mod 2) = 1">
>   <xsl:variable name="next_index" select="number(position() + 1)" />
>   <!--[<xsl:value-of select="position()" />,<xsl:value-of
> select="$next_index" />]-->
>   (<xsl:value-of select="." />,<xsl:value-of
> select="$letters[$next_index]"
> />)
>  </xsl:if>
> </xsl:for-each>
>
> I checked out the xsl faq, and I found a posting of
> Jeni's that showed how to copy a sorted list into a variable, but
> it doesn't seem to be working for me.
> (I'm using MSXML3 in case that matters...)
>
> <xsl:variable name="letterlist">
>  <xsl:for-each select="/ALPHABET/LETTER">
>   <xsl:sort select="." />
>   <xsl:copy-of select="." />
>  </xsl:for-each>
> </xsl:variable>
>
> <!-- nothing comes out... -->
> <xsl:value-of select="$letterlist" />
>
> Thanks,
> -Ollie Rutherfurd
> fruhstuck@xxxxxxxxxxxxxx
>
>
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>
>


 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
Keywords