Мне потребовалось некоторое время ... Я собирался сдаться, но все же продолжил:)
Недостатком функции key является то, что сгенерированный ключ всегда будет для всего xml. Следовательно, вы должны объединить дополнительную информацию в своем ключе, чтобы сделать его более конкретным. Например, ниже я объединяю положение узла записей, так что я получаю ключи для разных фамилий для записей.
Вот xslt:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="yes"/>
<xsl:key name="distinct-surname" match="contact" use="concat(generate-id(..), '|', surname)"/>
<xsl:template match="records">
<xsl:for-each select="contact[generate-id() = generate-id(key('distinct-surname', concat(generate-id(..), '|', surname))[1])]">
<xsl:sort select="surname" />
<xsl:value-of select="surname" />,<br />
<xsl:for-each select="key('distinct-surname', concat(generate-id(..), '|', surname))">
<xsl:sort select="forename" />
<xsl:value-of select="forename" /> (<xsl:value-of select="title" />)<br />
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Это результат:
Jones,
Amy (Dr)
Anne (Ms)
Indy (Dr)
Smith,
John (Mr)
Mary (Mrs)
Peter (Mr)
Jones,
Harry (Dr)
Mandy (Dr)
Sally (Ms)
Smith,
Elizabeth (Mrs)
George (Mr)
James (Mr)
Обратите внимание, что результат также сортируется по именам. Если вы не хотите сортировать по именам, вам нужно удалить строку <xsl:sort select="forename" />