XSLT preceding-sibling Issue following XSL:Sort

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Hi All
I am attempting to produce a xml transformation using xslt.
In one section I have duplicate record elements that need to be filtered to unique records. To do this I am sorting the elements and then conditionally copying the record to the output xml only if the current Record name doesnt match the preceding
sibiling name.
The problem is in identifying the value of the attribute of the preceding Record. I have inserted a <TestValue> element to display the value being passed into the ST_RecordDetails Template.
Sample XML
<pre class="prettyprint <?xml version=1.0 encoding=iso-8859-1?>
<ST_Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="Schema_Record Schema_Record.xsd

<RecordTable>
<RecordTable_NewRecords>
<ST_RecordDetails ST_Name="Rec_E" >
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level= "No </ST_RecordClass>
<ST_RecordClass ClassName="Brd" Level= "0 </ST_RecordClass>
</ST_RecordClasses>
</ST_RecordDetails>
<ST_RecordDetails ST_Name="Rec_D" >
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level= "No </ST_RecordClass>
<ST_RecordClass ClassName="Protection" Level= "1 </ST_RecordClass>
<ST_RecordClass ClassName="Rgr" Level= "2 </ST_RecordClass>
</ST_RecordClasses>
</ST_RecordDetails>
<ST_RecordDetails ST_Name="Rec_A
<ST_RecordClasses>
<ST_RecordClass ClassName="Brd" Level= "0 </ST_RecordClass>
</ST_RecordClasses>
</ST_RecordDetails>
<ST_RecordDetails ST_Name="Rec_B
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level= "No </ST_RecordClass>
<ST_RecordClass ClassName="Brd" Level= "0 </ST_RecordClass>
</ST_RecordClasses>
</ST_RecordDetails>

<ST_RecordDetails ST_Name="Rec_D
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level= "No </ST_RecordClass>
<ST_RecordClass ClassName="Protection" Level= "1 </ST_RecordClass>
<ST_RecordClass ClassName="Rgr" Level= "2 </ST_RecordClass>
</ST_RecordClasses>
</ST_RecordDetails>

<ST_RecordDetails ST_Name="Rec_E
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level= "No </ST_RecordClass>
<ST_RecordClass ClassName="Animal" Level= "0 </ST_RecordClass>
<ST_RecordClass ClassName="Rgr" Level= "0 </ST_RecordClass>
</ST_RecordClasses>
</ST_RecordDetails>

</RecordTable_NewRecords>

<ST_RecordFilters>
<ST_Record RecordName="Rec_A" Known="Yes" Prepared="0 </ST_Record>
<ST_Record RecordName="Rec_B" Known="Yes" Prepared="0 </ST_Record>
</ST_RecordFilters>

</RecordTable>

</ST_Data>
[/code]
XSLT Code
<pre class="prettyprint <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="RecordTable_NewRecords
<RecordTable_NewRecords>
<xsl:for-each select ="ST_RecordDetails
<xsl:sort select ="@ST_Name"/>
<xsl:call-template name ="ST_RecordDetails
<xsl:with-param name ="LastRecord" select ="preceding-sibling::ST_RecordDetails[1]/@ST_Name"/>
</xsl:call-template >

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

<xsl:template name ="ST_RecordDetails
<xsl:param name ="LastRecord"/>
<TestValue>
<xsl:value-of select ="$LastRecord[1]"/>
</TestValue>
<xsl:if test="@ST_Name!=$LastRecord[1]
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:if >
</xsl:template>

</xsl:stylesheet>
[/code]
Output
<pre class="prettyprint <?xml version="1.0" encoding="utf-8"?>
<ST_Data xsi:schemaLocation="Schema_Record Schema_Record.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance

<RecordTable>

<RecordTable_NewRecords>
<TestValue>Rec_D</TestValue>
<ST_RecordDetails ST_Name="Rec_A
<ST_RecordClasses>
<ST_RecordClass ClassName="Brd" Level="0" />
</ST_RecordClasses>
</ST_RecordDetails>
<TestValue>Rec_A</TestValue>
<ST_RecordDetails ST_Name="Rec_B
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level="No" />
<ST_RecordClass ClassName="Brd" Level="0" />
</ST_RecordClasses>
</ST_RecordDetails>
<TestValue>Rec_E</TestValue>
<ST_RecordDetails ST_Name="Rec_D
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level="No" />
<ST_RecordClass ClassName="Protection" Level="1" />
<ST_RecordClass ClassName="Rgr" Level="2" />
</ST_RecordClasses>
</ST_RecordDetails>
<TestValue>Rec_B</TestValue>
<ST_RecordDetails ST_Name="Rec_D
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level="No" />
<ST_RecordClass ClassName="Protection" Level="1" />
<ST_RecordClass ClassName="Rgr" Level="2" />
</ST_RecordClasses>
</ST_RecordDetails>
<TestValue></TestValue>
<ST_RecordDetails ST_Name="Rec_E
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level="No" />
<ST_RecordClass ClassName="Brd" Level="0" />
</ST_RecordClasses>
</ST_RecordDetails>
<TestValue>Rec_D</TestValue>
<ST_RecordDetails ST_Name="Rec_E
<ST_RecordClasses>
<ST_RecordClass ClassName="Core" Level="No" />
<ST_RecordClass ClassName="Animal" Level="0" />
<ST_RecordClass ClassName="Rgr" Level="0" />
</ST_RecordClasses>
</ST_RecordDetails>
</RecordTable_NewRecords>

<ST_RecordFilters>
<ST_Record RecordName="Rec_A" Known="Yes" Prepared="0" />
<ST_Record RecordName="Rec_B" Known="Yes" Prepared="0" />
</ST_RecordFilters>

</RecordTable>

</ST_Data>[/code]
Notice the duplicate Rec_D and Rec_E elements in the RecordTable_NewRecords.
If anyone can suggest what is going wrong here I would be grateful.
Kind regards
Ian


View the full article
 
Back
Top