Ответ от nonnb, скорее всего, указывает на проблему, но не на эффективное решение («более дешевая» ось лучше, но сама по себе она не делает скорость такой, как при индексации данных).
Обратите внимание, что большая проблема заключается в том, что предикат выражения XPath делает еще один полный обход дерева для каждой оценки. Вы должны использовать ключи для подобных вещей; это (в большинстве или даже во всех реализациях XSLT) делает возможным индексированный поиск, тем самым значительно сокращая время выполнения.
Определение ключей для фильмов, групп и шоу по id:
<xsl:key name="filmByTag" match="film" use="tag" />
<xsl:key name="groupsByFilm" match="group" use="tag" />
<xsl:key name="showsByFilm" match="show" use="film" />
<xsl:key name="showsByGroup" match="show" use="group" />
А затем используйте его следующим образом (не проверено, но вы должны понять):
<xsl:variable name="films" select="key('filmByTag', @id)/@id" />
<xsl:apply-templates select="key('showsByFilm', $films)/@id|key('showsByGroups', key('groupsByFilm', $films)/@id)/@id">