This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Dynamic XSL Sorting - Is there a way like this?


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

<xsl:output method="html" encoding="UTF-8"/>
<xsl:param name="sortBy" select="'Name'"/>

<xsl:template match="/">
	<!-- Count the rate changes to verify have records -->
 	<xsl:if test="count(HRISReport/Participants/Participant/Plans/Plan/ContributionRateChang
es/ContributionRateChange/RateChanges/RateChange) > 0">	
You don't need to count the elements, only check for existence:

<xsl:if test="HRISReport/Participants/Participant/Plans/Plan/
 ContributionRateChanges/ContributionRateChange/RateChanges/RateChange">

		<link rel='stylesheet' href='/stylesheet.css'/>
		<HTML>
		<HEAD>
		<TITLE>Deferral Pct Changes</TITLE>
		</HEAD>
			<BODY>
				<table class='datatable' cellspacing='1'>
					<tr>
						<td class='ttitle' colspan='13'>Deferral Pct Changes</td>
					</tr>
					<tr>
						<td class='theader' colspan='13'>
							From <xsl:value-of select="normalize-space(HRISReport/@StartDate)"/> - To <xsl:value-of select="normalize-space(HRISReport/@EndDate)"/>
						</td>
					</tr>
					<tr>
						<td class='theader'>SSN</td>
						<td class='theader'>Last Name</td>
						<td class='theader'>First Name</td>
						<td class='theader'>Participant Group</td>
						<td class='theader'>ID Code</td>
						<td class='theader'>HCE Code</td>
						<td class='theader'>Participation<br/>Date</td>
						<td class='theader'>Request Date</td>
						<td class='theader'>Contribution<br/>Acct</td>
						<td class='theader'>Old<br/>Percent</td>
						<td class='theader'>New<br/>Percent</td>
						<td class='theader'>Old<br/>Amount</td>
						<td class='theader'>New<br/>Amount</td>
					</tr>
					
						<xsl:for-each select="HRISReport/Participants/Participant/Plans/Plan/ContributionRateChanges/C
ontributionRateChange/RateChanges/RateChange">
							<xsl:sort select="@*[name(.)=$sortBy]"/>

							<tr>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../../../../../@SSN)"/></td>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../../../../../LastName)"/></td>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../../../../../FirstName)"/></td>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../../../@Group)"/></td>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../../../@ID)"/></td>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../HighCompCode)"/></td>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../ParticipationDate)"/></td>
								<td class='tdatal'><xsl:value-of select="normalize-space(../../RateEffectiveDate)"/></td>
								<td class="tdatal"><xsl:value-of select="normalize-space(@Name)"/></td>
								<td class="tdatar"><xsl:value-of select="normalize-space(format-number(OldPercent,'#0.00'))"/></td>
								<td class="tdatar"><xsl:value-of select="normalize-space(format-number(NewPercent,'#0.00'))"/></td>						
								<td class="tdatar"><xsl:value-of select="normalize-space(format-number(OldAmount,'###0.00'))"/></td>						
								<td class="tdatar"><xsl:value-of select="normalize-space(format-number(NewAmount,'###0.00'))"/></td>					
							</tr>
						</xsl:for-each>
				</table>
			</BODY>
		</HTML>
	</xsl:if>
</xsl:template>
</xsl:stylesheet>
Please don't use TABs for indenting, but 2 or 4 spaces - this makes your mail/code more readable.


The issue is the sort.  If I use and hard code the following it works:
<xsl:for-each select="HRISReport/Participants/Participant/Plans/Plan/ContributionRateChanges/C
ontributionRateChange/RateChanges/RateChange">
	<xsl:sort select="../../../../../../LastName"/>
	<xsl:sort select="../../../../../../@SSN"/>

This sorts properly but if I try to pass in a parameter things start to fail.

The following works:
<xsl:param name="sortBy" select="'Name'"/>

works if the sort reads:
<xsl:sort select="@*[name(.)=$sortBy]"/>

<xsl:param name="sortBy" select="'OldPercent'"/>
 works if the sort reads:
<xsl:sort select="*[name(.)=$sortBy]"/>

But how do I sort off of LastName,FirstName or SSN as a parameter.  None of these fields appear to work unless I hardcode the sort.  I know this is a long post and I am terribly sorry but I have been fight this for a couple of days.  Thank you in advance.
The problem are the different levels of your XML elements. Like you are navigating on the tree to the correct elements/attributes in the hard-coded version, you must do it in the parameterized version. I.e. you have to use something like '../../../../../../@SSN' as parameter for sorting. Problem: Dynamic evaluating of an XPATH expression isn't possible in pure XSLT 1, but using extension function evaluate() in many processors. If your sort elements are all on the same level, you can do something like

<xsl:sort select="../../../../../../*[name()=$sortBy] | ../../../../../../@*[name()=$sortBy]"/>

if their are no attributes and elements with the same name. But you will have a problem with your "multiple level sort possibilities". Maybe other people know a better solution than

<xsl:sort select="(*|@* | ../*|../@* | ../../*|../../@* | ../../../*|../../../@* | ../../../../*|../../../../@* | ../../../../../*|../../../../../@* | ../../../../../../*|../../../../../../@*)[name() = $sortBy]"/>

Regards,

Joerg


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]