Hi My Input is something like this.
9837
You have a template in your XSLT that ignores PartPosition
<xsl:template match="DamagePosition|DamageCode|PartPosition"/>
Therefore, when you do <xsl:apply-templates/>
in your copy
template, because you are positioned on a DamagePosition
at this point, the above template will match the child PartPosition
and simply ignore it.
Perhaps you should be ignoring DamageSeqNumber
instead of PartPosition
at this point?
Also, you probably don't really need the copy
template at all. Instead, change the call to it, to simply get all the child elements of the key, and then let the identity template take care of it.
<xsl:apply-templates select="key('kuserID',DamageCode)/*" />
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kuserID" match="DamagePosition" use="DamageCode"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:sort select="DamageCode" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="DamagePosition|DamageCode|DamageSeqNumber"/>
<xsl:template match="DamagePosition[generate-id() = generate-id(key('kuserID', DamageCode)[1])]">
<DamagePosition>
<xsl:copy-of select="DamageCode"/>
<xsl:copy-of select="DamageSeqNumber"/>
<xsl:apply-templates select="key('kuserID',DamageCode)/*" />
</DamagePosition>
</xsl:template>
</xsl:stylesheet>
This doesn't quite give the output you show in your question, because you show two OperationPosition
elements in your output, although there is only one in your input.
EDIT: If you wanted OperationPosition
elements before PartPosition
elements, you could replace the existing <xsl:apply-templates select="key('kuserID',DamageCode)/*" />
with these two lines instead:
<xsl:apply-templates select="key('kuserID',DamageCode)/OperationPosition" />
<xsl:apply-templates select="key('kuserID',DamageCode)/*[not(self::OperationPosition)]" />