Re: [xsl] Sorting Two Dimensional Table

Subject: Re: [xsl] Sorting Two Dimensional Table
From: David Carlisle <davidc@xxxxxxxxx>
Date: Mon, 15 Oct 2007 20:14:27 +0100
<x>
<titles>
	<key>z</key>
	<key>a</key>
	<value>valueX</value>
</titles>



<entries>
  <entry>
    <key name="a" value="b" />
    <key name="z" value="c" />
    <value>myValue1</value>
  </entry>
  <entry>
    <key name="a" value="b" />
    <key name="z" value="d" />
    <value>5</value>
  </entry>
  <entry>
    <key name="a" value="a" />
    <key name="z" value="c" />
    <value>myValue3</value>
  </entry>
  <entry>
    <key name="a" value="b" />
    <key name="z" value="d" />
    <value>4</value>
  </entry>
</entries>
</x>


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
		xmlns:xs="http://www.w3.org/2001/XMLSchema";
		exclude-result-prefixes="xs">
  
  <xsl:variable name="k1" as="xs:string+">
    <xsl:perform-sort select="x/titles/key">
      <xsl:sort select="."/>
    </xsl:perform-sort>
  </xsl:variable>

  <xsl:output indent="yes"/>

  <xsl:template match="x">
 

   <table>
     <tr>
       <xsl:for-each select="$k1,titles/value">
	 <th><xsl:value-of select="."/></th>
       </xsl:for-each>
     </tr>

    <xsl:call-template name="entries">
      <xsl:with-param name="k" select="$k1"/>
      <xsl:with-param name="e" select="entries/entry"/>
    </xsl:call-template>
   </table>

  </xsl:template>

  <xsl:template name="entries">
    <xsl:param name="k"/>
    <xsl:param name="e"/>
    <xsl:choose>
      <xsl:when test="empty($k)">
	<xsl:apply-templates select="$e">
	  <xsl:sort lang="en" select="value"/>
	</xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
	<xsl:for-each-group select="$e" group-by="key[@name=$k[1]]/@value">
	  <xsl:sort lang="en" select="key[@name=$k[1]]/@value"/>
	  <xsl:call-template name="entries">
	    <xsl:with-param name="k" select="$k[position()!=1]"/>
	    <xsl:with-param name="e" select="current-group()"/>
	  </xsl:call-template>
	</xsl:for-each-group>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

<xsl:template match="entry">
    <xsl:variable name="here" select="."/>
    <tr>
      <xsl:for-each select="$k1">
	 <td><xsl:value-of select="$here/key[@name=current()]/@value"/></td>
       </xsl:for-each>
       <td><xsl:value-of select="value"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>


$ saxon8 2dsort.xml  2dsort.xsl 
<?xml version="1.0" encoding="UTF-8"?>
<table>
   <tr>
      <th>a</th>
      <th>z</th>
      <th>valueX</th>
   </tr>
   <tr>
      <td>a</td>
      <td>c</td>
      <td>myValue3</td>
   </tr>
   <tr>
      <td>b</td>
      <td>c</td>
      <td>myValue1</td>
   </tr>
   <tr>
      <td>b</td>
      <td>d</td>
      <td>4</td>
   </tr>
   <tr>
      <td>b</td>
      <td>d</td>
      <td>5</td>
   </tr>
</table>

________________________________________________________________________
The Numerical Algorithms Group Ltd is a company registered in England
and Wales with company number 1249803. The registered office is:
Wilkinson House, Jordan Hill Road, Oxford OX2 8DR, United Kingdom.

This e-mail has been scanned for all viruses by Star. The service is
powered by MessageLabs. 
________________________________________________________________________

Current Thread