How to Modify XSLT to Reorder XML Elements Based on Specific Criteria?
Posted: Fri Jul 12, 2024 9:34 am
I'm working on an XML transformation project and need some help with XSLT. I have an XML file with multiple <Student> elements, each containing <HUSID>, <SURNAME>, <NUMHUS>, and <COURSEID> elements. My goal is to reorder the <COURSEID> elements within each <Student> element so that all <COURSEID> values are nested within a single <InstancePeriod> element.
Here's a simplified version of my XML:
And here's the XSLT I'm currently using:
The output I'm getting is:
But what I want is:
Could anyone help me adjust my XSLT to achieve the desired output? Any tips or suggestions would be greatly appreciated!
Here's a simplified version of my XML:
Code: Select all
<dataroot>
<Student>
<HUSID>idno</HUSID>
<SURNAME>Second Name</SURNAME>
<NUMHUS>idno2</NUMHUS>
<COURSEID>course1</COURSEID>
</Student>
<Student>
<HUSID>idno</HUSID>
<SURNAME>Surname</SURNAME>
<NUMHUS>idno2</NUMHUS>
<COURSEID>course2</COURSEID>
</Student>
<Student>
<HUSID>idno</HUSID>
<SURNAME>Surname</SURNAME>
<NUMHUS>idno2</NUMHUS>
<COURSEID>course3</COURSEID>
</Student>
</dataroot>
Code: Select all
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="dataroot">
<dataroot>
<xsl:apply-templates select="Student[not(HUSID = preceding-sibling::Student/HUSID)]" mode="student"/>
</dataroot>
</xsl:template>
<xsl:template match="Student" mode="student">
<xsl:variable name="husid" select="HUSID"/>
<xsl:variable name="surname" select="SURNAME"/>
<Student>
<HUSID><xsl:value-of select="$husid"/></HUSID>
<SURNAME><xsl:value-of select="$surname"/></SURNAME>
<xsl:apply-templates select="/dataroot/Student[HUSID/text()=$husid]" mode="instanceperiod"/>
</Student>
</xsl:template>
<xsl:template match="Student" mode="instanceperiod">
<xsl:variable name="courseid" select="COURSEID"/>
<Instance>
<NUMHUS><xsl:value-of select="NUMHUS"/></NUMHUS>
<InstancePeriod>
<COURSEID><xsl:value-of select="$courseid"/></COURSEID>
</InstancePeriod>
</Instance>
</xsl:template>
</xsl:stylesheet>
Code: Select all
<dataroot>
<Student>
<HUSID>idno</HUSID>
<SURNAME>Second Name</SURNAME>
<Instance>
<NUMHUS>idno2</NUMHUS>
<InstancePeriod>
<COURSEID>course1</COURSEID>
</InstancePeriod>
</Instance>
<Instance>
<NUMHUS>idno2</NUMHUS>
<InstancePeriod>
<COURSEID>course2</COURSEID>
</InstancePeriod>
</Instance>
<Instance>
<NUMHUS>idno2</NUMHUS>
<InstancePeriod>
<COURSEID>course3</COURSEID>
</InstancePeriod>
</Instance>
</Student>
</dataroot>
Code: Select all
<dataroot>
<Student>
<HUSID>idno</HUSID>
<SURNAME>Second Name</SURNAME>
<Instance>
<NUMHUS>idno2</NUMHUS>
<InstancePeriod>
<COURSEID>course1</COURSEID>
<COURSEID>course2</COURSEID>
<COURSEID>course3</COURSEID>
</InstancePeriod>
</Instance>
</Student>
</dataroot>