Это преобразование :
<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="kByMode-StartCharAndModPos" match="term"
use="concat(count(../preceding-sibling::mode),
'+',
substring(name,1,1)
)"/>
<xsl:template match="node()|@*" mode="identity">
<xsl:copy>
<xsl:apply-templates mode="identity"
select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<modes>
<xsl:apply-templates/>
</modes>
</xsl:template>
<xsl:template match="mode">
<mode pos="{position()}">
<xsl:apply-templates select=
"term[generate-id()
=
generate-id(key('kByMode-StartCharAndModPos',
concat(count(../preceding-sibling::mode),
'+',
substring(name,1,1)
)
)[1]
)
]">
<xsl:sort select="substring(name,1,1)"/>
</xsl:apply-templates>
</mode>
</xsl:template>
<xsl:template match="term">
<starting letter="{substring(name,1,1)}">
<xsl:apply-templates mode="identity" select=
"key('kByMode-StartCharAndModPos',
concat(count(../preceding-sibling::mode),
'+',
substring(name,1,1)
)
)
"/>
</starting>
</xsl:template>
</xsl:stylesheet>
при применении к этому документу XML :
<modes>
<mode>
<term>
<name>Adams</name>
</term>
<term>
<name>Allen</name>
</term>
<term>
<name>Brooks</name>
</term>
<term>
<name>Cameron</name>
<name>Campbell</name>
</term>
</mode>
<mode>
<term>
<name>Apple</name>
</term>
<term>
<name>Egan</name>
<name>Elkin</name>
</term>
<term>
<name>Fisher</name>
<name>Foster</name>
</term>
<term>
<name>Hall</name>
</term>
<term>
<name>ghjghj</name>
</term>
<term>
<name>Jackson</name>
</term>
</mode>
<mode>
<term>
<name>Lewis</name>
</term>
<term>
<name>Murray</name>
<name>Myers</name>
</term>
</mode>
</modes>
создает требуемые индексы для каждого <mode>
(форматирование в html не выполняется):
<modes>
<mode pos="1">
<starting letter="A">
<term>
<name>Adams</name>
</term>
<term>
<name>Allen</name>
</term>
</starting>
<starting letter="B">
<term>
<name>Brooks</name>
</term>
</starting>
<starting letter="C">
<term>
<name>Cameron</name>
<name>Campbell</name>
</term>
</starting>
</mode>
<mode pos="2">
<starting letter="A">
<term>
<name>Apple</name>
</term>
</starting>
<starting letter="E">
<term>
<name>Egan</name>
<name>Elkin</name>
</term>
</starting>
<starting letter="F">
<term>
<name>Fisher</name>
<name>Foster</name>
</term>
</starting>
<starting letter="g">
<term>
<name>ghjghj</name>
</term>
</starting>
<starting letter="H">
<term>
<name>Hall</name>
</term>
</starting>
<starting letter="J">
<term>
<name>Jackson</name>
</term>
</starting>
</mode>
<mode pos="3">
<starting letter="L">
<term>
<name>Lewis</name>
</term>
</starting>
<starting letter="M">
<term>
<name>Murray</name>
<name>Myers</name>
</term>
</starting>
</mode>
</modes>
Обратите внимание: Для группирования используется мюнхенский метод группировки, содержащий как положение режима, так и название термина.