Subject: RE: [xsl] Dynamically define number of xsl:sort stmts using parameters From: "Angela Williams" <Angela.Williams@xxxxxxxxxxxxxxxxxx> Date: Wed, 28 Mar 2007 16:40:47 -0500 |
Thanks! This allowed me to handle the additional requirement to allow the user to specify ascending or descending. -----Original Message----- From: Andrew Welch [mailto:andrew.j.welch@xxxxxxxxx] Sent: Wednesday, March 28, 2007 11:36 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: [xsl] Dynamically define number of xsl:sort stmts using parameters 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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Dynamically define number, Andrew Welch | Thread | RE: [xsl] Dynamically define number, cknell |
RE: [xsl] XSLT parsers in a C/C++ A, Michael Kay | Date | [xsl] Unique Nodes, Karthik |
Month |