Re: [xsl] Resolving Variable Redefining Issues in a For Each

Subject: Re: [xsl] Resolving Variable Redefining Issues in a For Each
From: David Carlisle <davidc@xxxxxxxxx>
Date: Wed, 30 Mar 2005 12:36:51 +0100
> The problem is re assigning the variable in the for loop.

I don't see any variable re-assignments (ie use of xsl:variable twice
with the same name in the same scope. If you did that you woul dget an
error reported.




   	<xsl:template match="/">
   		<xsl:element name="Root">

You could just use <Root> here

   
   			<xsl:variable name="URecordID" 
   select="/Root/Wrapper/Detail/Unit[not(./@RecordID=preceding::Unit/@RecordID)]"/>
   
OK , although perhaps using preceding-sibling:: might be a bit more
efficient (neither is particularly efficient if your lists are very
long), see the faq entries for grouping.

   			<xsl:for-each select="$URecordID">
   				<xsl:variable name="thisRID"
   				select="."/>

I don't think you need thisRID it is only used at places where it is the
current node, so just using . would be simpler.

   				<xsl:variable name="RecordIDCodes" 
   select="/Root/Wrapper/Detail/Unit[./@RecordID=$thisRID/@RecordID]"/>

You could use current()/@RecordID if you got rid of $thisRID but
otherwise this is OK, again it is inefficient for large lists, using a
key is likely to be quicker, see "muenchian grouping"


   				<xsl:element name="Record">
   					<xsl:attribute name="Type">
   						<xsl:value-of select="$thisRID/@RecordID"/>
   					</xsl:attribute>
   
You could write these linesjust as <Record Type="{@RecordID}">
        
   					<xsl:variable name="URecordIDCodes" 
   select="$RecordIDCodes[not(./@Code=preceding::Unit/@Code)]"/>

This is your probem: your uniqueness test fails here as preceding::Unit
checks if the code appears anywhere earlier in the document, not if it
occurs earlier within $RecordIDCodes, the faq or jeni's list have
examples of using concat to make up a multiple level key, but just to
fix the code you have without using keys you want to check preceding
nodes that have the same recordid so that is

   select="$RecordIDCodes[not(@Code=preceding::Unit[@RecordID=current()/@recordID]/@Code)]"/>
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   					<xsl:for-each select="$URecordIDCodes">
   						<xsl:variable name="thisCodes" select="."/>
   						<xsl:variable name="UCode" 
   select="$RecordIDCodes[./@Code=$thisCodes/@Code]"/>
   						<xsl:element name="RCVCTN">
   							<xsl:attribute name="Code">
   								<xsl:value-of select="$thisCodes/@Code"/>
   							</xsl:attribute>
   							<xsl:attribute name="Total">
   								<xsl:value-of select="sum($UCode/@Total)"/>
   							</xsl:attribute>

again you don't need thisCode variable and this could be more simply written as
<RCVCTN Code={@Code}" Total="{sum($UCode/@Total)}"/>

   						</xsl:element>
   					</xsl:for-each>
   				</xsl:element>
   			</xsl:for-each>
   
   		</xsl:element>
   	</xsl:template>
   </xsl:stylesheet>
   
   
   	
David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

Current Thread