RE: [xsl] <xsl:sort>

Subject: RE: [xsl] <xsl:sort>
From: aspsa <aspsa@xxxxxxxxxxxxx>
Date: Sat, 07 May 2005 14:48:39 -0400
George,

Thanks again for your reply and example.

I must be doing something else incorrectly. Let me expand upon my original
question. As for the first half of the XML document, the occurrences of
<paragraph>, <subheader> and <image> elements occur in random order. This
part of the document is presented narratively. However, the second half is
well-structured and data-centric.

Please find below the entire XSLT stylesheet. I removed a great deal of
presentation-related markup in order to avoid clutter. Please note that I
used

	<xsl:apply-templates select="paragraph[1]" />

because I wanted present the first paragraph differently from the remain
ones. In the <xsl:for-each> loop I stripped out the presentation markup that
would visually set apart other nodes.

Any way, the focal point is the <xsl:for-each> loop. I suspect my problem
lays with the fact that <xsl:apply-templates> is being used twice.

Again your feedback is most appreciated.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

  <xsl:template match="/">
    <html>
      <head><title>A title...</title></head>
      <body><xsl:apply-templates select="document" /></body>
    </html>
  </xsl:template>

  <xsl:template match="document">
    <xsl:value-of select="header" /><br />
    <xsl:text>Date: </xsl:text>
    <xsl:value-of select="@month" />
    <xsl:text>, </xsl:text>
    <xsl:value-of select="@year" />
    <hr />
    <xsl:apply-templates select="paragraph[1]" />
    <hr />
    <p></p>

    <xsl:for-each select="child::node()">
      <!--
            Avoid the first two nodes occuring in document order.
            They have already been address above.
      -->
      <xsl:if test="position() > 2">
        <xsl:apply-templates select="." />
      </xsl:if>
    </xsl:for-each>
    <xsl:apply-templates select="product">
      <xsl:sort select="category" data-type="number" order="descending" />
    </xsl:apply-templates>
    <p></p>
  </xsl:template>

  <xsl:template match="subheader">
    <xsl:value-of select="." />
  </xsl:template>

  <xsl:template match="paragraph">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="bold">
    <xsl:value-of select="." />
  </xsl:template>

  <xsl:template match="italic">
    <xsl:value-of select="." />
  </xsl:template>

  <xsl:template match="image">
    <xsl:text>Image Information:</xsl:text><br />
    <xsl:value-of select="caption" />
    <hr />
    <xsl:text>Source: </xsl:text>
    <xsl:value-of select="source" /><br />
    <xsl:text>Dimensions (w/h): </xsl:text>
    <xsl:text>(</xsl:text>
    <xsl:value-of select="width" />
    <xsl:text>, </xsl:text>
    <xsl:value-of select="height" />
    <xsl:text>)</xsl:text>
    <p></p>
  </xsl:template>

  <xsl:template match="product">
    <xsl:text>Product Information:</xsl:text><br />
    <xsl:text>Category ID: </xsl:text>
    <xsl:choose>
      <xsl:when test="string(category) != ''">
        <xsl:value-of select="category" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>No ID available</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>Part Name</xsl:text><br />
    <xsl:choose>
      <xsl:when test="string(partname) != ''">
        <xsl:value-of select="partname" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>[Unavailable]</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <br /><br />
    <xsl:if test="string(description) != ''">
      <xsl:text>Description</xsl:text><br />
      <xsl:value-of select="description" />
      <br />
    </xsl:if>
    <xsl:text>Company Information</xsl:text><br />
    <xsl:text>Company ID: </xsl:text>
    <xsl:choose>
      <xsl:when test="string(company/id) != ''">
        <xsl:value-of select="company/id" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>No ID available</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    </p>
    <xsl:apply-templates select="company" />
    <p></p>
  </xsl:template>

  <xsl:template match="company">
    <xsl:value-of select="name" /><br />
    <xsl:value-of select="city" />
    <xsl:text>, </xsl:text>
    <xsl:value-of select="state" /><br />
    <xsl:value-of select="country" />
    <hr />
    <xsl:if test="string(contact) != ''">
      <xsl:text>Contact: </xsl:text><xsl:value-of select="contact" /><br />
    </xsl:if>
    <xsl:text>Telephone: </xsl:text><xsl:value-of select="phone" /><br />
    <xsl:if test="string(fax) != ''">
      <xsl:text>Fax: </xsl:text><xsl:value-of select="fax" /><br />
    </xsl:if>
    <xsl:if test="string(email) != ''">
      <xsl:text>Email: </xsl:text><xsl:value-of select="email" /><br />
    </xsl:if>
    <xsl:text>Web Site: </xsl:text><xsl:value-of select="url" /><br />
    <xsl:if test="string(primeid) != ''">
      <xsl:text>Prime ID: </xsl:text><xsl:value-of select="primeid" />
    </xsl:if>
    <p></p>
  </xsl:template>

</xsl:stylesheet>

-----Original Message-----
From: George Cristian Bina [mailto:george@xxxxxxx]
Sent: Saturday, May 07, 2005 4:31 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] <xsl:sort>


XML:
<?xml version="1.0" encoding="UTF-8"?>
<document>
     <header/>
     <paragraph/>
     <subheader/>
     <paragraph/>
     <product>
         <partname/>
         <category>3</category>
     </product>
     <product>
         <partname/>
         <category>1</category>
     </product>
     <product>
         <partname/>
         <category>2</category>
     </product>
</document>

XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
     <xsl:template match="document">
         <xsl:for-each select="child::node()">
             <!-- whatever processing you want to do -->
         </xsl:for-each>
         <xsl:apply-templates select="product">
             <xsl:sort select="category" data-type="number"
order="descending"/>
         </xsl:apply-templates>
     </xsl:template>
</xsl:stylesheet>

All the XSLT transformers I tried (Saxon6.5.3, Saxon 8.4, Xalan 2.5.1,
MSXML .NET, 4.0, 3.0 and XSLTProc) gave me:
3
2
1

Best Regards,
George
---------------------------------------------------------------------
George Cristian Bina
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com


aspsa wrote:
> Thanks for the reply, George.
>
> I gave your suggestion a try, but it still does not affect the sort order
of
> <product> elements. In the resultant document, they continue to appear in
> the orginal XML document order.
>
>
> Respectfully,
>
> ASP

Current Thread