Search code examples
xsltxslt-grouping

XSLT Help - Compare preceding node and counter increment if the date is different


I have xml where each worker can have multiple events. The events need not be grouped but if there are two events with same Effective_Date, I'd like to increment the sequence. Below is sample xml:

XML:

<?xml version="1.0" encoding="UTF-8"?>
<wd:Report_Data xmlns:wd="urn:com.workday.report/ERP-HCM-CR_ASSIGNMENTS_REPORT_V4">
    <wd:Report_Entry>
        <wd:Worker_group>
            <wd:UNIQUE_IDENTIFIER>2168636</wd:UNIQUE_IDENTIFIER>
        </wd:Worker_group>
        <wd:Caregiver_Events_group>
            
            <wd:ASSIGNMENT_NUMBER>2168636-03012008E01</wd:ASSIGNMENT_NUMBER>
            <wd:EFFECTIVE_DATE>2008-03-01-08:00</wd:EFFECTIVE_DATE>
            <wd:EFFECTIVE_SEQUENCE>1</wd:EFFECTIVE_SEQUENCE>
            
        </wd:Caregiver_Events_group>
        <wd:Caregiver_Events_group>
            
            <wd:ASSIGNMENT_NUMBER>2168636-03012008E01</wd:ASSIGNMENT_NUMBER>
            <wd:EFFECTIVE_DATE>2019-12-01-08:00</wd:EFFECTIVE_DATE>
            <wd:EFFECTIVE_SEQUENCE>1</wd:EFFECTIVE_SEQUENCE>
            
        </wd:Caregiver_Events_group>
        <wd:Caregiver_Events_group>
            
            <wd:ASSIGNMENT_NUMBER>2168636-03012008E01</wd:ASSIGNMENT_NUMBER>
            <wd:EFFECTIVE_DATE>2019-12-01-08:00</wd:EFFECTIVE_DATE>
            <wd:EFFECTIVE_SEQUENCE>1</wd:EFFECTIVE_SEQUENCE>
        </wd:Caregiver_Events_group>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Worker_group>
            <wd:UNIQUE_IDENTIFIER>2188946</wd:UNIQUE_IDENTIFIER>
            
        </wd:Worker_group>
        
        <wd:Caregiver_Events_group>
        <wd:ASSIGNMENT_NUMBER>2188946-04272015E01</wd:ASSIGNMENT_NUMBER>
        <wd:EFFECTIVE_DATE>2015-04-27-07:00</wd:EFFECTIVE_DATE>
        <wd:EFFECTIVE_SEQUENCE>1</wd:EFFECTIVE_SEQUENCE>
        </wd:Caregiver_Events_group>
        <wd:Caregiver_Events_group>
            
            <wd:COUNTRY_CODE>US</wd:COUNTRY_CODE>
            <wd:ASSIGNMENT_NUMBER>2188946-04272015E01</wd:ASSIGNMENT_NUMBER>
            <wd:EFFECTIVE_DATE>2019-12-01-08:00</wd:EFFECTIVE_DATE>
            <wd:EFFECTIVE_SEQUENCE>1</wd:EFFECTIVE_SEQUENCE>
            
        </wd:Caregiver_Events_group>
        <wd:Caregiver_Events_group>
            
            <wd:ASSIGNMENT_NUMBER>2188946-04272015E01</wd:ASSIGNMENT_NUMBER>
            <wd:EFFECTIVE_DATE>2019-12-01-08:00</wd:EFFECTIVE_DATE>
            <wd:EFFECTIVE_SEQUENCE>1</wd:EFFECTIVE_SEQUENCE>
            
        </wd:Caregiver_Events_group>
    </wd:Report_Entry>
</wd:Report_Data>

Portion of xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"
    xmlns:wd="urn:com.workday.report/ERP-HCM-CR_ASSIGNMENTS_REPORT_V4" version="2.0">
    <xsl:output method="text"/>
    <xsl:variable name="linefeed" select="'&#xD;&#xA;'"/>
    <xsl:variable name="pipe" select="'|'"/>
    <xsl:variable name="EffectiveStartDate" select="'01-01-1951'"/>
    <xsl:variable name="EffectiveEndDate" select="'4712-12-31'"/>
    <xsl:variable name="i" select="position()"/>

    <xsl:param name="quote">"</xsl:param>
    <xsl:template match="/">
        <!--  File Header Record  -->
        <xsl:call-template name="Write-Header-Record0"/>

        <!--  File Detail Layout  -->
        <xsl:for-each select="wd:Report_Data/wd:Report_Entry">
            <xsl:for-each select="wd:Caregiver_Events_group">

                <xsl:call-template name="Write-Detail-Record"/>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="Write-Header-Record0">
        <xsl:text>Unique ID|Assignment Number|Effective Date|Sequence</xsl:text>
        <xsl:value-of select="$linefeed"/>
    </xsl:template>



    <xsl:template name="Write-Detail-Record">

        <xsl:value-of select="../wd:Worker_group/wd:UNIQUE_IDENTIFIER"/>
        <xsl:value-of select="$pipe"/>

        <xsl:value-of select="wd:ASSIGNMENT_NUMBER"/>
        <xsl:value-of select="$pipe"/>

        <xsl:value-of select="format-date(wd:EFFECTIVE_DATE, '[Y0001]-[M01]-[D01]')"/>
        <xsl:value-of select="$pipe"/>
        <xsl:choose>
            <xsl:when
                test="(preceding-sibling::node()[wd:EFFECTIVE_DATE = current()/wd:EFFECTIVE_DATE])">
                <xsl:value-of
                    select="preceding-sibling::node()/wd:EFFECTIVE_SEQUENCE + current()/wd:EFFECTIVE_SEQUENCE"/>
                
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="wd:EFFECTIVE_SEQUENCE"/>
            </xsl:otherwise>
        </xsl:choose>

        <xsl:value-of select="$linefeed"/>
    </xsl:template>

</xsl:stylesheet>
        

Can someone please assist. I know the value-of select cannot add two elements. If a worker (report_entry) has three events (caregiver_events_group) with same effective date, I would expect to see sequence of 1, 2, 3 on three rows.

Expecting output:

2168636|2168636-03012008E01|2008-03-01-08:00|1
2168636|2168636-03012008E01|2019-12-01-08:00|1
2168636|2168636-03012008E01|2019-12-01-08:00|2
2188946|2188946-04272015E01|2015-04-27-07:00|1
2188946|2188946-04272015E01|2019-12-01-08:00|1
2188946|2188946-04272015E01|2019-12-01-08:00|2

Solution

  • Would something like this work for you:

    XSLT 2.0

    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="urn:com.workday.report/ERP-HCM-CR_ASSIGNMENTS_REPORT_V4">
    <xsl:output method="text" encoding="UTF-8"/>
    
    <xsl:template match="/Report_Data">
        <!-- header -->
        <xsl:text>Unique ID|Assignment Number|Effective Date|Sequence&#10;</xsl:text>
        <!-- data -->
        <xsl:for-each select="Report_Entry">
            <xsl:variable name="id" select="Worker_group/UNIQUE_IDENTIFIER" />
            <xsl:for-each-group select="Caregiver_Events_group" group-by="EFFECTIVE_DATE">
                <xsl:variable name="date" select="format-date(EFFECTIVE_DATE, '[Y0001]-[M01]-[D01]')"/>
                <xsl:for-each select="current-group()">
                    <xsl:value-of select="$id"/>
                    <xsl:text>|</xsl:text>
                    <xsl:value-of select="ASSIGNMENT_NUMBER"/>
                    <xsl:text>|</xsl:text>
                    <xsl:value-of select="$date"/>
                    <xsl:text>|</xsl:text>
                    <xsl:value-of select="position()"/>
                    <xsl:text>&#10;</xsl:text>
                </xsl:for-each>
            </xsl:for-each-group>
        </xsl:for-each>
    </xsl:template>
    
    </xsl:stylesheet>