Мне было интересно, как этот предикат ([1]) закодирован как 1 всегда в
мюнхенская группировка.
Это просто :
Функция key()
создает все узлы для данной группы, и мы хотим взять только один узел из любой группы.
Не гарантируется, что во всех группах будет два или более узлов - у некоторых может быть только один узел.
Вот почему безопасно и удобно брать первый (и, возможно, единственный) узел из каждой группы.
Мы могли бы с тем же успехом выполнить группировку, взяв последний узел из каждой группы (но это будет менее эффективно):
<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="kNumByMod3" match="num"
use=". mod 3"/>
<xsl:template match=
"num[generate-id()
=
generate-id(key('kNumByMod3', . mod 3)[last()])
]
">
3k + <xsl:value-of select=". mod 3"/>:
<xsl:text/>
<xsl:copy-of select="key('kNumByMod3', . mod 3)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
при применении к этому документу XML :
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
дает желаемый, правильно сгруппированный результат :
3k + 2:
<num>02</num>
<num>05</num>
<num>08</num>
3k + 0:
<num>03</num>
<num>06</num>
<num>09</num>
3k + 1:
<num>01</num>
<num>04</num>
<num>07</num>
<num>10</num>