Andrey Bushman
Andrey Bushman

Reputation: 12516

How to enumerate the sorted records in XSL 1.0?

Sorry for my weak English.

How to enumerate the sorted records in XSL 1.0? Fragment of my code:

...
<tbody>
  <xsl:for-each select="/doc:resources/doc:record">
    <xsl:sort select="@id"/>
    <xsl:choose>
      <xsl:when test="(position() mod 2) = 0">
        <tr bgcolor="#C0C0C0">
          <td>
            <xsl:number format="1"/>
          </td>
          <td>
            <xsl:value-of select="@id"/>
          </td>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
      </xsl:when>
      <xsl:otherwise>
        <tr>
          <td>
            <xsl:number format="1"/>
          </td>
          <td>
            <xsl:value-of select="@id"/>
          </td>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</tbody>
...

Incorrect result screen:

http://imglink.ru/pictures/01-04-12/92605b06b8b2c2670bba868c61288e9b.jpg

Regards

Upvotes: 2

Views: 182

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243549

The reason for the incorrect numbers is that xsl:number doesn't know about the (dynamic) sorting and uses the structure of the original, unsorted document.

Here is one complete, short and simple, correct solution, using position(). In addition to this, no conditional instructions (xsl:choose, xsl:when, xsl:otherwise, xsl:if`) are used at all:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="xxx">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <html>
       <table>
        <xsl:apply-templates select="*">
          <xsl:sort select="@id"/>
        </xsl:apply-templates>
     </table>
  </html>
 </xsl:template>

 <xsl:template match="doc:record">
   <xsl:variable name="vColor" select=
    "substring('C0C0C0FFFFFF', 6*(position() mod 2)+1, 6)"/>

   <tr bgcolor="#{$vColor}">
            <td>
                <xsl:value-of select="position()"/>
            </td>
            <td>
                <xsl:value-of select="@id"/>
            </td>
            <td>
                <xsl:value-of select="."/>
            </td>
   </tr>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied to the following XML document (none was provided!):

<doc:resources xmlns:doc="xxx">
  <doc:record id="dadasd">
    some value1
  </doc:record>
  <doc:record id="hkjhkhkhk">
    some value2
  </doc:record>
  <doc:record id="xvxvxvxv">
    some value3
  </doc:record>
  <doc:record id="afasf">
    some value4
  </doc:record>
  <doc:record id="iuyiyuiy">
    some value5
  </doc:record>
</doc:resources>

the wanted, correct result is produced:

<html xmlns:doc="xxx">
   <table>
      <tr bgcolor="#FFFFFF">
         <td>1</td>
         <td>afasf</td>
         <td>
                some value4

         </td>
      </tr>
      <tr bgcolor="#C0C0C0">
         <td>2</td>
         <td>dadasd</td>
         <td>
            some value1

         </td>
      </tr>
      <tr bgcolor="#FFFFFF">
         <td>3</td>
         <td>hkjhkhkhk</td>
         <td>
                some value2

         </td>
      </tr>
      <tr bgcolor="#C0C0C0">
         <td>4</td>
         <td>iuyiyuiy</td>
         <td>
                some value5

         </td>
      </tr>
      <tr bgcolor="#FFFFFF">
         <td>5</td>
         <td>xvxvxvxv</td>
         <td>
                some value3

         </td>
      </tr>
   </table>
</html>

Upvotes: 0

Tomalak
Tomalak

Reputation: 338326

<xsl:for-each select="/doc:resources/doc:record">
  <xsl:sort select="@id"/>
  <tr>
    <xsl:if test="position() mod 2 = 0">
      <xsl:attribute name="bgcolor">#C0C0C0</xsl:attribute>
    </xsl:if> 
    <td>
      <xsl:value-of select="position()" />
    </td>
    <td>
      <xsl:value-of select="@id"/>
    </td>
    <td>
      <xsl:value-of select="."/>
    </td>
  </tr>
</xsl:for-each>

Upvotes: 2

Related Questions