clatadia
clatadia

Reputation: 55

Matching the first element when it can occure in different places of the hierarchy?

So, there is this element that can occur in a lot of elements and I should remove all of them that are within a specific element or its descendants. I can't seem to figure out how to approach it, because the relation is not "fixed". So I provided an example to get my point across:

Input:

<a>
    <b>
        <d value="1"></d>
    <b/>
    <b>
        <c>
            <d value="2"></d>
            <d value="1"></d>
        </c>
        <d value="1">
        <d value="2">
    <b/>
</a>

Wanted output:

<a>
    <b>
        <d value="1"></d>
    <b/>
    <b>
        <c>
            <d value="2"></d>
        </c>
    <b/>
</a>

You see the output just has the first element with value="1" or value="2". Is this even possible with XSL?

Upvotes: 0

Views: 46

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117102

You could use a variation on Muenchian grouping:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="d-by-value" match="d" use="@value" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- remove duplicate d's -->
<xsl:template match="d[count(. | key('d-by-value', @value)[1]) != 1]"/>

</xsl:stylesheet>

Upvotes: 1

Related Questions