xsltxslt-1.0muenchian-grouping

Remove duplicates but only on parent level XSLT 1.0


I tried to find a solution to my problem, there are many solutions for deleting "plain" duplicates, but I couldn't find one. My problem is that I should somehow delete the duplicates, but unfortunately the parent node has the same name as the child node, so when I search for duplicates and delete them, it also deletes the child nodes, which should be. How can I delete only the parent nodes and leave the child nodes?

My XML:

    <?xml version="1.0" encoding="UTF-8"?>
<invoices>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="1878.95"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1878.95"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="0.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="0.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1878.95"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="0.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="1900.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1900.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="0.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="0.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1900.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="0.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_2">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="1900.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1900.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_2"/>
                </cost>
                <amounts>
                    <amount localamount="2700.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_2">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_2"/>
        </cost>
        <amounts>
            <amount localamount="2700.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1900.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_2"/>
                </cost>
                <amounts>
                    <amount localamount="2700.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_2">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_3"/>
        </cost>
        <amounts>
            <amount localamount="500.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_3"/>
                </cost>
                <amounts>
                    <amount localamount="500.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_3">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="0.00"/>
        </amounts>
    </invoice>
    <allinvoice>
        <invoice buyer="Company_3">
            <invoicenumbers>
                <invoicenumber name="1234"/>
            </invoicenumbers>
            <cost>
                <COSTGROUP name="Group_1"/>
            </cost>
            <amounts>
                <amount localamount="0.00"/>
            </amounts>
        </invoice>
    </allinvoice>
    <invoice buyer="Company_3">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_2"/>
        </cost>
        <amounts>
            <amount localamount="100.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_3">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_2"/>
                </cost>
                <amounts>
                    <amount localamount="100.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_3">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_3"/>
                </cost>
                <amounts>
                    <amount localamount="5000.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_3">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_3"/>
        </cost>
        <amounts>
            <amount localamount="5000.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_3">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_2"/>
                </cost>
                <amounts>
                    <amount localamount="100.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_3">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_3"/>
                </cost>
                <amounts>
                    <amount localamount="5000.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
</invoices>

My XSLT:

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:key name="more_than_one" match="invoice" use="concat(@buyer,
        '|', invoicenumbers/invoicenumber/@name)"/>
    
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="invoice[not(generate-id() = generate-id(key('more_than_one', concat(@buyer,
        '|', invoicenumbers/invoicenumber/@name))[1]))]"/>

</xsl:stylesheet>

My Result:

    <?xml version="1.0" encoding="UTF-8"?>
<invoices>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="1234"> </invoicenumber>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"> </COSTGROUP>
        </cost>
        <amounts>
            <amount localamount="1878.95"> </amount>
        </amounts>
        <allinvoice> </allinvoice>
    </invoice>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="5678"> </invoicenumber>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"> </COSTGROUP>
        </cost>
        <amounts>
            <amount localamount="1900.00"> </amount>
        </amounts>
        <allinvoice> </allinvoice>
    </invoice>
    <invoice buyer="Company_2">
        <invoicenumbers>
            <invoicenumber name="1234"> </invoicenumber>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"> </COSTGROUP>
        </cost>
        <amounts>
            <amount localamount="1900.00"> </amount>
        </amounts>
        <allinvoice> </allinvoice>
    </invoice>
    <invoice buyer="Company_2">
        <invoicenumbers>
            <invoicenumber name="5678"> </invoicenumber>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_3"> </COSTGROUP>
        </cost>
        <amounts>
            <amount localamount="500.00"> </amount>
        </amounts>
        <allinvoice> </allinvoice>
    </invoice>
    <invoice buyer="Company_3">
        <invoicenumbers>
            <invoicenumber name="1234"> </invoicenumber>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"> </COSTGROUP>
        </cost>
        <amounts>
            <amount localamount="0.00"> </amount>
        </amounts>
    </invoice>
    <allinvoice> </allinvoice>
    <invoice buyer="Company_3">
        <invoicenumbers>
            <invoicenumber name="5678"> </invoicenumber>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_2"> </COSTGROUP>
        </cost>
        <amounts>
            <amount localamount="100.00"> </amount>
        </amounts>
        <allinvoice> </allinvoice>
    </invoice>
</invoices>

What I want:

    <?xml version="1.0" encoding="UTF-8"?>
<invoices>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="1878.95"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1878.95"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="0.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_1">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="1900.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1900.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_1">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="0.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_2">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="1900.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_1"/>
                </cost>
                <amounts>
                    <amount localamount="1900.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="1234"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_2"/>
                </cost>
                <amounts>
                    <amount localamount="2700.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_2">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_3"/>
        </cost>
        <amounts>
            <amount localamount="500.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_2">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_3"/>
                </cost>
                <amounts>
                    <amount localamount="500.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
    <invoice buyer="Company_3">
        <invoicenumbers>
            <invoicenumber name="1234"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_1"/>
        </cost>
        <amounts>
            <amount localamount="0.00"/>
        </amounts>
    </invoice>
    <allinvoice>
        <invoice buyer="Company_3">
            <invoicenumbers>
                <invoicenumber name="1234"/>
            </invoicenumbers>
            <cost>
                <COSTGROUP name="Group_1"/>
            </cost>
            <amounts>
                <amount localamount="0.00"/>
            </amounts>
        </invoice>
    </allinvoice>
    <invoice buyer="Company_3">
        <invoicenumbers>
            <invoicenumber name="5678"/>
        </invoicenumbers>
        <cost>
            <COSTGROUP name="Group_2"/>
        </cost>
        <amounts>
            <amount localamount="100.00"/>
        </amounts>
        <allinvoice>
            <invoice buyer="Company_3">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_2"/>
                </cost>
                <amounts>
                    <amount localamount="100.00"/>
                </amounts>
            </invoice>
            <invoice buyer="Company_3">
                <invoicenumbers>
                    <invoicenumber name="5678"/>
                </invoicenumbers>
                <cost>
                    <COSTGROUP name="Group_3"/>
                </cost>
                <amounts>
                    <amount localamount="5000.00"/>
                </amounts>
            </invoice>
        </allinvoice>
    </invoice>
</invoices>

Thank you for your help. Regards.


Solution

  • The sample data is too long to check but your description sounds as if you want to improve your match patterns to e.g.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
        <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
        <xsl:strip-space elements="*"/>
        
        <xsl:key name="more_than_one" match="/invoices/invoice" use="concat(@buyer,
            '|', invoicenumbers/invoicenumber/@name)"/>
        
        <xsl:template match="node()|@*">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
        
        <xsl:template match="/invoices/invoice[not(generate-id() = generate-id(key('more_than_one', concat(@buyer,
            '|', invoicenumbers/invoicenumber/@name))[1]))]"/>
    
    </xsl:stylesheet>