RE: [xsl] problem with multiple xsl:sort elements

Subject: RE: [xsl] problem with multiple xsl:sort elements
From: "Josh Canfield" <josh.canfield@xxxxxxxxxxxx>
Date: Mon, 5 Jan 2004 18:33:59 -0800
Your problem is here:
<xsl:if test="not(GLAccountNumber = following::GLAccountNumber)">

following::GLAccountNumber is returning the next GLAccountNumber in document order, not in the order that the for-each is iterating over the elements.

One solution would be to group the AccountLineItem elements together by GLAccountNumber and then output the subtotal after processing each GLAccountNumber. 

<xsl:key name="account-by-number" match="/ArrayOfAccountLineItem/AccountLineItem" use="GLAccountNumber"/>

<xsl:template match="ArrayOfAccountLineItem">

	<!-- iterate over distinct account numbers -->
	<xsl:for-each select="AccountLineItem[GLAccountNumber[not(. = preceding::GLAccountNumber)]]">
		<xsl:sort select="GLAccountNumber" data-type="text" order="ascending"/>
		<!-- iterate over all matching account numbers -->
		<xsl:for-each select="key('account-by-number', GLAccountNumber)">
			<xsl:sort select="substring(SettleDate,1,10)" data-type="text" order="ascending"/>
			<xsl:sort select="LineItemID" data-type="number" order="ascending"/>

			<xsl:apply-templates select="."/>

		</xsl:for-each>

		<!-- Summary line, used to be in xsl:if in the AccountLineItem template-->
		<tr>
			<td colspan="11">
				&#xA0;
			</td>
		</tr>
		<tr>
			<td colspan="4">
				&#xA0;
			</td>
			<td colspan="2" class="fieldName" align="center">
				Total by Object Code:
			</td>
			<td class="bottomFieldInfo" align="right">
<xsl:value-of select="format-number(sum(key('subTotal', GLAccountNumber)/Amount[. &gt; 1]), '#.00')"/>
			</td>
			<td>
				&#xA0;
			</td>
			<td class="bottomFieldInfo" align="right" style="padding-right:5px">
<xsl:value-of select="translate(format-number(sum(key('subTotal', GLAccountNumber)/Amount[. &lt; 0]), '#.00'), '-', '')"/>
			</td>
			<td colspan="2">
				&#xA0;
			</td>
		</tr>
		<tr>
			<td colspan="11">
				&#xA0;
			</td>
		</tr>

		
	</xsl:for-each>
</table>
</xsl:template>

<xsl:template match="AccountLineItem">	
			<tr>
				<td class="fieldInfo">
					<xsl:value-of select="substring(LineItemName,1,35)"/>
				</td>
				<td class="fieldInfo">
					<xsl:value-of select="position()"/>
				</td>
				<td class="fieldInfo">
					<xsl:value-of select="GLAccountNumber"/>
				</td>
				<td class="fieldInfo">
					<xsl:value-of select="substring(RegistrantFullName,1,19)"/>
				</td>
				<td class="fieldInfo">
					<xsl:value-of select="concat(substring(SettleDate,6,2), '/', substring(SettleDate,9,2), '/', substring(SettleDate,1,4))"/>
				</td>				
				<td align="right" class="fieldInfo">
					<xsl:value-of select="LineItemID"/>
				</td>
				<td class="fieldInfo" align="right">
					<xsl:choose>
						<xsl:when test="Amount &gt; 0">
							<xsl:value-of select="format-number(Amount, '#.00')"/>
						</xsl:when>
						<xsl:otherwise>
							&#xA0;
						</xsl:otherwise>
					</xsl:choose>
				</td>
				<td>
					&#xA0;
				</td>
				<td align="right" class="fieldInfo" style="padding-right: 5px;">
					<xsl:choose>
						<xsl:when test="Amount &lt; 0">
							<xsl:value-of select="translate(format-number(Amount, '#.00'), '-', '')"/>
						</xsl:when>
						<xsl:otherwise>
							&#xA0;
						</xsl:otherwise>
					</xsl:choose>
				</td>
				<td class="fieldInfo">
					<xsl:value-of select="substring(PaymentType,1,12)"/>					
				</td>
				<td class="fieldInfo">
					<xsl:value-of select="substring(PaymentReference,1,15)"/>
				</td>
			</tr>
</xsl:template>


Hope this helps,
Josh

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


Current Thread