EDN Admin
Well-known member
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"
>
<xslutput 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
<xslaram 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
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"
>
<xslutput 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
<xslaram 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