Subject: Re: [xsl] 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 |
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>
<?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>
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.
cheers andrew
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Dynamically define number, Angela Williams | Thread | RE: [xsl] Dynamically define number, Angela Williams |
Re: [xsl] XSLT parsers in a C/C++ A, Colin Adams | Date | Re: [xsl] Use same xml file with di, David Carlisle |
Month |