I. Вероятно, самое эффективное решение XSLT 1.0 :
<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:key name="kWSPlayByTitle" match="play[a='Will Smith']"
use="t"/>
<xsl:key name="kActorByTitle" match="a"
use="../t"/>
<xsl:template match="/">
<Plays>
<xsl:apply-templates select=
"*/play[generate-id()
=
generate-id(key('kWSPlayByTitle',t)[1])
]"/>
</Plays>
</xsl:template>
<xsl:template match="play">
<Play title="{t}">
<xsl:apply-templates select="key('kActorByTitle',t)"/>
</Play>
</xsl:template>
<xsl:template match="a">
<star><xsl:value-of select="."/></star>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к предоставленному документу XML :
<director>
<play>
<t>Nutcracker</t>
<a>Tom Cruise</a>
</play>
<play>
<t>Nutcracker</t>
<a>Robin Williams</a>
</play>
<play>
<t>Grinch Stole Christmas</t>
<a>Will Smith</a>
</play>
<play>
<t>Grinch Stole Christmas</t>
<a>Mel Gibson</a>
</play>
</director>
желаемый результат получен :
<Plays>
<Play title="Grinch Stole Christmas">
<star>Will Smith</star>
<star>Mel Gibson</star>
</Play>
</Plays>
Примечание :
Эффективность достигается с помощью клавиш как для всех пьес, в которых участвовал Мелл Гибсон, так и для всех актеров, которые принимали участие в данной (названной) пьесе.
Даже если пьеса с Мелом Гибсоном была указана более одного раза (возможно, из-за случайной ошибки ...), она будет указана только один раз в результате .
II. Простое и эффективное решение XSLT 2.0 :
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<Plays>
<xsl:for-each-group select="play[a='Mel Gibson']"
group-by="t">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</Plays>
</xsl:template>
<xsl:template match="play">
<Play title="{t}">
<xsl:for-each-group select="../play[t = current()/t]/a"
group-by=".">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</Play>
</xsl:template>
<xsl:template match="a">
<star>
<xsl:value-of select="."/>
</star>
</xsl:template>
</xsl:stylesheet>