Hope you guys are doing well.Thank you so much in advance.Your help will really appreciated.
Got into trouble to create the XSLT (v2.0) for below requirement.Not getting how to achieve it.
Requirement: Generate a unique Event Id based on consultative date and time type for each employees.
Example: For employee EMP12345 is on Annual leave for date 2015-03-31, Sick leave for period 2015-04-01 to 2015-04-03 and 2015-04-15 to 2015-04-16.
So there are 2 consecutive dated sick leave .So need to generate the two unique event id.
Please refer the below expected output.
XML
<?xml version='1.0' encoding='UTF-8'?>
<Data>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Annual</Time_type>
<Date>2015-03-31</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-01</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-02</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-03</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-15</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-16</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12346</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-01</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12346</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-02</Date>
<Hours>6</Hours>
</Employee>
</Data>
Expected output:
Employee ID,Time Type,Date,Hours,Event ID
EMP12345,Annual,2015-03-31,6,
EMP12345,Sick,2015-04-01,6,12344EMP12345
EMP12345,Sick,2015-04-02,6,12344EMP12345
EMP12345,Sick,2015-04-03,6,12344EMP12345
EMP12345,Sick,2015-04-15,6,22344EMP12345
EMP12345,Sick,2015-04-16,6,22344EMP12345
EMP12346,Sick,2015-04-01,6,11111EMP12346
EMP12346,Sick,2015-04-02,6,11111EMP12346
Thanks,
Deepak
One possible way to do this, is to use xsl:for-each-group
, and group starting by the Employee
elements where the date is not one day after the previous one (i.e they are the start of a new group)
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))]">
I am sure if you have a specific rule for generating the EventId, but one possible way would be as follows
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
You would then use current-group()
to output all the rows in that particular group, with the same EventId. Try this XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:output method="text" />
<xsl:template match="Data">
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))]">
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
<xsl:for-each select="current-group()">
<xsl:value-of select="Employee_ID" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Time_type" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Date" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Hours" />
<xsl:text>,</xsl:text>
<xsl:value-of select="$EventId" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied to you current XML, the following is output
EMP12345,Annual,2015-03-31,6,EMP12345-1
EMP12345,Sick,2015-04-01,6,EMP12345-2
EMP12345,Sick,2015-04-02,6,EMP12345-2
EMP12345,Sick,2015-04-03,6,EMP12345-2
EMP12345,Sick,2015-04-15,6,EMP12345-3
EMP12345,Sick,2015-04-16,6,EMP12345-3
EMP12346,Sick,2015-04-01,6,EMP12346-4
EMP12346,Sick,2015-04-02,6,EMP12346-4
Note, this does assume the Employee
elements are sorted in Employee_id
, Date
, and time_type
order.