Cette transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vallLeaves" select="//node()[not(node())]"/>
<xsl:template match="/">
$vallLeaves:
<xsl:copy-of select="$vallLeaves"/>
$vallDistinctLeaves:
<xsl:for-each select="$vallLeaves">
<xsl:if test=
"generate-id()
=
generate-id($vallLeaves[@name
=
current()/@name
]
[1]
)
">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
lorsqu'il est appliqué sur le document XML fourni:
<node name="A">
<node name="B">
<node name="C"/>
<node name="D"/>
<node name="E"/>
</node>
<node name="D"/>
<node name="E"/>
</node>
produit le résultat souhaité, correct:
$vallLeaves:
<node name="C"/>
<node name="D"/>
<node name="E"/>
<node name="D"/>
<node name="E"/>
$vallDistinctLeaves:
<node name="C"/>
<node name="D"/>
<node name="E"/>
II. XSLT 2.0 Solution:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vallLeaves" select="//node()[not(node())]"/>
<xsl:variable name="vallDistinctLeaves" as="element()*">
<xsl:for-each-group select="$vallLeaves" group-by="@name">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:variable>
<xsl:template match="/">
$vallLeaves:
<xsl:sequence select="$vallLeaves"/>
$vallDistinctLeaves:
<xsl:sequence select="$vallDistinctLeaves"/>
</xsl:template>
</xsl:stylesheet>
lorsque cette transformation est appliquée sur le même document XML (ci-dessus), les mêmes résultats corrects sont produits:
$vallLeaves:
<node name="C"/>
<node name="D"/>
<node name="E"/>
<node name="D"/>
<node name="E"/>
$vallDistinctLeaves:
<node name="C"/>
<node name="D"/>
<node name="E"/>
Bonne question (1). Voir ma réponse pour deux solutions - XSLT 1.0 et XSLT 2.0. :) –