[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Dynamically define number of xsl:sort stmts using

Subject: Re: Dynamically define number of xsl:sort stmts using parameters
From: "Andrew Welch" <andrew.j.welch@xxxxxxxxx>
Date: Wed, 28 Mar 2007 17:36:16 +0100
Re:  Dynamically define number of xsl:sort stmts using
On 3/28/07, Angela Williams <Angela.Williams@xxxxxxxxxxxxxxxxxx> wrote:
Aha!

My esteemed colleague came up with a better idea - gosh, I hate it when
I forget the power of xpath!

<?xml version="1.0" encoding="UTF-8"?>
<employees>
  <employee hireDate="04/23/1999">
    <last>Hill</last>
    <first>Phil</first>
    <salary>100000</salary>
  </employee>

  <employee hireDate="09/01/1998">
    <last>Herbert</last>
    <first>Johnny</first>
    <salary>95000</salary>
  </employee>

  <employee hireDate="08/20/2000">
    <last>Hill</last>
    <first>Graham</first>
    <salary>89000</salary>
  </employee>

  <sort order="1">last</sort>
  <sort order="2">first</sort>
</employees>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:saxon="http://saxon.sf.net/">

<xsl:output method="text" />

  <xsl:template match="employees">
    <xsl:variable name="sort1" select="sort[@order='1']" />
    <xsl:variable name="sort2" select="sort[@order='2']" />
    <xsl:variable name="sort3" select="sort[@order='3']" />
    <xsl:variable name="sort4" select="sort[@order='4']" />

    <xsl:for-each select="employee">
      <xsl:sort
          select="if ($sort1) then saxon:evaluate($sort1) else 'foo'" />
      <xsl:sort
          select="if ($sort2) then saxon:evaluate($sort2) else 'foo'" />
      <xsl:sort
          select="if ($sort3) then saxon:evaluate($sort3) else 'foo'" />
      <xsl:sort
          select="if ($sort4) then saxon:evaluate($sort4) else 'foo'" />


Last: <xsl:apply-templates select="last" /> First: <xsl:apply-templates select="first" /> Salary: <xsl:apply-templates select="salary" /> Hire Date: <xsl:apply-templates select="@hireDate" /> <xsl:text> </xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>


Here's a way of sorting dynamically without extensions:


<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="fn">

<xsl:variable name="employees" select="/employees/employee"/>
<xsl:variable name="sortValues" select="/employees/sort" as="xs:string+"/>

<xsl:function name="fn:performSort" as="element()+">
	<xsl:param name="list" as="element()+"/>
	<xsl:param name="sortKey" as="xs:string+"/>
	
	<xsl:variable name="sortedList" as="element()+">
		<xsl:for-each select="$list">
			<xsl:sort select="*[name() = $sortKey[1]]"/>
			<xsl:copy-of select="."/>
		</xsl:for-each>
	</xsl:variable>
	
	<xsl:sequence select="if ($sortKey[2]) then
							fn:performSort($sortedList, subsequence($sortKey, 2))
							else $sortedList"/>
</xsl:function>

<xsl:template match="/">
	<xsl:sequence select="fn:performSort($employees, $sortValues)"/>
</xsl:template>

</xsl:stylesheet>

You call the performSort() function with a list of elements to sort,
and a list of child element names to sort with, and it recursively
sorts by each one.

hope this helps,

cheers
andrew

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.