XSLT preceding-sibling Issue following XSL:Sort
-
Wednesday, June 27, 2012 7:46 PM
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 doesn't 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
<?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>XSLT Code
<?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>Output
<?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>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

