Reputation: 39
I need to do a bit tricky mapping using xslt 1.0. need to do grouping only on the date part of the datetime
element. However the element contains the both date and time.Also after grouping need to add the hours.
Here is the input:
<Records>
<Record>
<empid>1</empid>
<datetime>10/10/2010 11:11:00 AM</datetime>
<hours>5</hours>
</Record>
<Record>
<empid>1</empid>
<datetime>10/10/2010 10:11:00 AM</datetime>
<hours>5</hours>
</Record>
<Record>
<empid>1</empid>
<datetime>10/11/2010 11:11:00 AM</datetime>
<hours>5</hours>
</Record>
<Record>
<empid>2</empid>
<datetime>10/10/2010 10:11:00 AM</datetime>
<hours>2</hours>
</Record>
<Record>
<empid>2</empid>
<datetime>10/10/2010 9:11:00 AM</datetime>
<hours>5</hours>
</Record>
</Records>
Expected output is:
<Records>
<Record>
<empid>1</empid>
<detail>
<date>10/10/2010</date>
<hours>10</hours>
</detail>
<detail>
<date>10/11/2010</date>
<hours>5</hours>
</detail>
</Record>
<Record>
<empid>2</empid>
<detail>
<date>10/10/2010</date>
<hours>7</hours>
</detail>
</Record>
</Records>
Appreciate for any help.
Upvotes: 1
Views: 117
Reputation: 243449
This transformation:
<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="kRecById" match="Record" use="empid"/>
<xsl:key name="kRecByDateId" match="Record"
use="concat(empid,'+',substring-before(datetime, ' '))"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"Record[generate-id()=generate-id(key('kRecById', empid)[1])]">
<Record>
<xsl:apply-templates select="empid"/>
<xsl:apply-templates mode="inGroup" select=
"key('kRecById', empid)
[generate-id()
=
generate-id(key('kRecByDateId',
concat(empid,'+',substring-before(datetime, ' ')))[1])]"/>
</Record>
</xsl:template>
<xsl:template match="Record" mode="inGroup">
<detail>
<date><xsl:value-of select="substring-before(datetime, ' ')"/></date>
<hours><xsl:value-of select=
"sum(key('kRecByDateId',
concat(empid,'+',substring-before(datetime, ' '))
)/hours)"/>
</hours>
</detail>
</xsl:template>
<xsl:template match="Record"/>
</xsl:stylesheet>
when applied on the provided XML document:
<Records>
<Record>
<empid>1</empid>
<datetime>10/10/2010 11:11:00 AM</datetime>
<hours>5</hours>
</Record>
<Record>
<empid>1</empid>
<datetime>10/10/2010 10:11:00 AM</datetime>
<hours>5</hours>
</Record>
<Record>
<empid>1</empid>
<datetime>10/11/2010 11:11:00 AM</datetime>
<hours>5</hours>
</Record>
<Record>
<empid>2</empid>
<datetime>10/10/2010 10:11:00 AM</datetime>
<hours>2</hours>
</Record>
<Record>
<empid>2</empid>
<datetime>10/10/2010 9:11:00 AM</datetime>
<hours>5</hours>
</Record>
</Records>
produces the wanted, correct result:
<Records>
<Record>
<empid>1</empid>
<detail>
<date>10/10/2010</date>
<hours>10</hours>
</detail>
<detail>
<date>10/11/2010</date>
<hours>5</hours>
</detail>
</Record>
<Record>
<empid>2</empid>
<detail>
<date>10/10/2010</date>
<hours>7</hours>
</detail>
</Record>
</Records>
Explanation:
Two nested Muenchian grouping s, the inner using a composite key.
Upvotes: 1