Search code examples
xmlxsltxslt-2.0

XSLT: How to check for duplicate entries and return only the entry that has active status (for that entry that has duplicate)?


I'm trying to output a text file that will remove a duplicate and only return the active one for that id that has duplicate. **Example if I have 2 entries in the xml but entries have same ID, only output the one with status active. While the others that dont have duplicates, just include in the output regardless if it's active or inactive.

For Example

<Report_Data>
    <Report_Entry>
        <id>1</id>
        <status>Inactive</status>
     </Report_Entry>
     <Report_Entry>
        <id>1</id>
        <status>Active</status>
     </Report_Entry>
     <Report_Entry>
        <id>3</id>
        <status>Active</status>
     </Report_Entry>
     <Report_Entry>
        <id>4</id>
        <status>Inactive</status>
     </Report_Entry>
 </Report_Data>

I tried to use xsl:for-each-group and group-by but not achieving the result.

<xsl:template match="Report_Data">
    <row>
        <text>id|status</text>
        <xsl:value-of select="$newline"/>
    </row>
    <xsl:for-each-group select="Report_Entry" group-by="id[../status='Active']">
        <row>
            <id>
                <xsl:value-of select="id"/>
                <xsl:value-of select="$delimiter"/>
            </id>
            <status>
                <xsl:value-of select="status"/>
             </status>
        </row>

The output is:

id|status
1|Active
3|Active

But the desired output is

id|status
1|Active
3|Active
4|Inactive

Tried this code but also returning the incorrect output

<xsl:for-each-group select="Report_Entry[status='Active']" group-by="id">

Thanks in advance. :)


Solution

  • My interpretation of your requirement would be:

    <xsl:template match="/Report_Data">
        <xsl:text>id|status&#10;</xsl:text>
        <xsl:for-each-group select="Report_Entry" group-by="id">
            <xsl:value-of select="id"/>
            <xsl:text>|</xsl:text>
            <xsl:value-of select="(current-group()[status='Active'], 
                                   current-group()[status='Inactive'])[1]/status"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each-group>
    </xsl:template>