Сначала вам нужно определить ключ для «группировки» всех элементов company вместе, которые имеют одну и ту же первую букву.
<xsl:key name="companyLetter" match="company" use="substring(text(), 1, 1)" />
Затем вы перебираете все элементы company.
<xsl:for-each select="options/companies/company">
Однако вы хотите обрабатывать элемент company только в том случае, если это первое вхождение этого элемента для его первой буквы. Вы делаете это, ища первую букву в первом элементе вашего ключа и проверяя, совпадает ли она. Сравнение элементов выполняется с помощью функции generate-id().
<xsl:variable name="firstLetter" select="substring(text(), 1, 1)" />
<xsl:if test="generate-id(.) = generate-id(key('companyLetter', $firstLetter)[1])" >
Помещение этого в целом дает
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="companyLetter" match="company" use="substring(text(), 1, 1)"/>
<xsl:template match="/root">
<select id="colors">
<xsl:for-each select="options/companies/company">
<xsl:sort select="text()"/>
<xsl:variable name="firstLetter" select="substring(text(), 1, 1)"/>
<xsl:if test="generate-id(.) = generate-id(key('companyLetter', $firstLetter)[1])">
<option>
<xsl:attribute name="value">
<xsl:value-of select="$firstLetter"/>
</xsl:attribute>
<xsl:value-of select="$firstLetter"/>
</option>
</xsl:if>
</xsl:for-each>
</select>
</xsl:template>
</xsl:stylesheet>
Для второго раскрывающегося списка вы можете использовать именованный шаблон, которому в качестве параметра передается буква. Вы можете найти все элементы для этой буквы, используя тот же ключ, что и выше.
<xsl:template name="Companies">
<xsl:param name="firstLetter"/>
<select>
<xsl:attribute name="id">
<xsl:value-of select="$firstLetter"/>
</xsl:attribute>
<xsl:for-each select="key('companyLetter', $firstLetter)">
<xsl:sort select="text()"/>
<option>
<xsl:attribute name="value">
<xsl:value-of select="@url"/>
</xsl:attribute>
<xsl:value-of select="text()"/>
</option>
</xsl:for-each>
</select>
</xsl:template>
Для вызова шаблона достаточно передать требуемый параметр, например
<xsl:call-template name="Companies">
<xsl:with-param name="firstLetter">B</xsl:with-param>
</xsl:call-template>
Конечно, вы можете использовать цикл for-each, если хотите показать все выпадающие списки для всех возможных первых букв.
person
Tim C
schedule
27.01.2010