Reputation: 11
XSLT Sorting and assign an unique number to each group: I want to sort and assign a unique number for each group after the sorting. sort based on <Type>
& <Location>
using xslt. Please see below for the input and output expected.
Input XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:Payload xmlns:ns1="http://abcd.ef.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:Detail>
<ns1:ID>141414</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1214</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>151515</ns1:ID>
<ns1:Type>MT</ns1:Type>
<ns1:Location>1215</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>313131</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>MM</ns1:Type>
<ns1:Location>1213</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>112233</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>112334</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
</ns1:Detail>
</ns1:Payload>
Output XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:Payload xmlns:ns1="http://abcd.ef.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:Detail>
<ns1:ID>112233</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
<ns1:MsgGroup>1</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>112334</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
<ns1:MsgGroup>1</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>313131</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
<ns1:MsgGroup>2</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
<ns1:MsgGroup>2</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>MM</ns1:Type>
<ns1:Location>1213</ns1:Location>
<ns1:MsgGroup>3</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>141414</ns1:ID>
<ns1:Type>MT</ns1:Type>
<ns1:Location>1214</ns1:Location>
<ns1:MsgGroup>4</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>151515</ns1:ID>
<ns1:Type>MT</ns1:Type>
<ns1:Location>1214</ns1:Location>
<ns1:MsgGroup>4</ns1:MsgGroup>
</ns1:Detail>
</ns1:Payload>
Upvotes: 1
Views: 241
Reputation: 3738
I'm going to take a stab at this even though there are inconsistencies between your input XML and expected output. :) You can tell me if what I produce is incorrect.
When this XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns1="http://abcd.ef.com" version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key
name="kDetail"
match="ns1:Detail"
use="concat(ns1:Type, '+', ns1:Location)" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates
select="ns1:Detail[
generate-id() =
generate-id(
key('
kDetail',
concat(ns1:Type, '+', ns1:Location)
)[1]
)
]">
<xsl:sort select="ns1:Location" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="ns1:Detail">
<xsl:variable name="vPos" select="position()" />
<xsl:for-each select="key('kDetail', concat(ns1:Type, '+', ns1:Location))">
<xsl:copy>
<xsl:apply-templates />
<ns1:MsgGroup>
<xsl:value-of select="$vPos" />
</ns1:MsgGroup>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
...is run against the provided XML (corrected, I think, to eliminate inconsistencies):
<?xml version="1.0" encoding="UTF-8"?>
<ns1:Payload
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns1="http://abcd.ef.com">
<ns1:Detail>
<ns1:ID>141414</ns1:ID>
<ns1:Type>MT</ns1:Type>
<ns1:Location>1214</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>151515</ns1:ID>
<ns1:Type>MT</ns1:Type>
<ns1:Location>1214</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>313131</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>MM</ns1:Type>
<ns1:Location>1213</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>112233</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>112334</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
</ns1:Detail>
</ns1:Payload>
...the wanted result is (I think) produced:
<?xml version="1.0"?>
<ns1:Payload
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns1="http://abcd.ef.com">
<ns1:Detail>
<ns1:ID>112233</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
<ns1:MsgGroup>1</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>112334</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1211</ns1:Location>
<ns1:MsgGroup>1</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>313131</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
<ns1:MsgGroup>2</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>SS</ns1:Type>
<ns1:Location>1213</ns1:Location>
<ns1:MsgGroup>2</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>123123</ns1:ID>
<ns1:Type>MM</ns1:Type>
<ns1:Location>1213</ns1:Location>
<ns1:MsgGroup>3</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>141414</ns1:ID>
<ns1:Type>MT</ns1:Type>
<ns1:Location>1214</ns1:Location>
<ns1:MsgGroup>4</ns1:MsgGroup>
</ns1:Detail>
<ns1:Detail>
<ns1:ID>151515</ns1:ID>
<ns1:Type>MT</ns1:Type>
<ns1:Location>1214</ns1:Location>
<ns1:MsgGroup>4</ns1:MsgGroup>
</ns1:Detail>
</ns1:Payload>
Upvotes: 1