Hi My Input is something like this.
<?xml version="1.0" encoding="UTF-8"?>
<Claim>
<Mileage>9837</Mileage>
<DamagePosition>
<DamageSeqNumber>3</DamageSeqNumber>
<DamageCode>2727004</DamageCode>
<PartPosition>
<SeqNumber>1</SeqNumber>
<PartNumber>A2035400253</PartNumber>
</PartPosition>
</DamagePosition>
<DamagePosition>
<DamageSeqNumber>1</DamageSeqNumber>
<DamageCode>2727004</DamageCode>
<PartPosition>
<SeqNumber>3</SeqNumber>
<PartNumber>A1409910055</PartNumber>
</PartPosition>
</DamagePosition>
<DamagePosition>
<DamageSeqNumber>8</DamageSeqNumber>
<DamageCode>2727004</DamageCode>
<OperationPosition>
<SeqNumber>8</SeqNumber>
<Opcode>02-2710-01</Opcode>
</OperationPosition>
</DamagePosition>
<DamagePosition>
<DamageSeqNumber>4</DamageSeqNumber>
<DamageCode>3221136</DamageCode>
<PartPosition>
<SeqNumber>4</SeqNumber>
<PartNumber>A2033202889</PartNumber>
</PartPosition>
</DamagePosition>
</Claim>
and desired output is :
<?xml version="1.0" encoding="UTF-8"?>
<Claim>
<Mileage>9837</Mileage>
<DamagePosition>
<DamageSeqNumber>3</DamageSeqNumber>
<DamageCode>2727004</DamageCode>
<OperationPosition>
<SeqNumber>8</SeqNumber>
<Opcode>02-2710-01</Opcode>
</OperationPosition>
<PartPosition>
<SeqNumber>1</SeqNumber>
<PartNumber>A2035400253</PartNumber>
</PartPosition>
<PartPosition>
<SeqNumber>3</SeqNumber>
<PartNumber>A1409910055</PartNumber>
</PartPosition>
<OperationPosition>
<SeqNumber>8</SeqNumber>
<Opcode>02-2710-01</Opcode>
</OperationPosition>
</DamagePosition>
<DamagePosition>
<DamageSeqNumber>4</DamageSeqNumber>
<DamageCode>3221136</DamageCode>
<PartPosition>
<SeqNumber>4</SeqNumber>
<PartNumber>A2033202889</PartNumber>
</PartPosition>
</DamagePosition>
</Claim>
I tried following 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
|PartPosition"/>
<xsl:template match=
"DamagePosition
[generate-id()
=
generate-id(key('kuserID', DamageCode)[1])
]">
<DamagePosition>
<xsl:copy-of select="DamageCode"/>
<xsl:apply-templates mode="copy" select="key('kuserID',DamageCode)" />
</DamagePosition>
</xsl:template>
<xsl:template match="DamagePosition" mode="copy">
<PartPosition>
<xsl:apply-templates/>
</PartPosition>
</xsl:template>
</xsl:stylesheet>
and it is giving me ouput like below, Though it is able to group child elements having same DamageCode, but not giving the desired ouput, it is not copying all tags under part position, only seqNumber is visible in output . Also Any help is much appreciated. Thanks for all the help.
<Claim>
<Mileage>9837</Mileage>
<DamagePosition>
<DamageCode>2727004</DamageCode>
<PartPosition>
<DamageSeqNumber>3</DamageSeqNumber>
</PartPosition>
<PartPosition>
<DamageSeqNumber>1</DamageSeqNumber>
</PartPosition>
<PartPosition>
<DamageSeqNumber>8</DamageSeqNumber>
<OperationPosition>
<SeqNumber>8</SeqNumber>
<Opcode>02-2710-01</Opcode>
</OperationPosition>
</PartPosition>
</DamagePosition>
<DamagePosition>
<DamageCode>3221136</DamageCode>
<PartPosition>
<DamageSeqNumber>4</DamageSeqNumber>
</PartPosition>
</DamagePosition>
</Claim>
You have a template in your XSLT that ignores
PartPosition
Therefore, when you do
<xsl:apply-templates/>
in yourcopy
template, because you are positioned on aDamagePosition
at this point, the above template will match the childPartPosition
and simply ignore it.Perhaps you should be ignoring
DamageSeqNumber
instead ofPartPosition
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.Try this XSLT
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 beforePartPosition
elements, you could replace the existing<xsl:apply-templates select="key('kuserID',DamageCode)/*" />
with these two lines instead: