Zastosowanie kluczy do grupowania w XSLT 1.0 (metoda Muencha)

Konieczność grupowanie węzłów jest dość często pojawiającym się problemem podczas pracy z Xslt. Niestety XSLT w wersji 1.0 nie posiada wbudowanych mechanizmów, które bezpośrednio wspomagałyby tę operację (XSLT 2.0 zawiera nowe instrukcje przeznaczone specjalnie do do tego celu). W jaki sposób więc radzić sobie z tym problemem? Jednym ze sposobów jest zastosowanie osi (axis) following-sibling (lub preceding-sibling). Załóżmy, że na wejście dostajemy następujący dokument Xml:

<root>
  <towar kraj="PL">marchew</towar>
  <towar kraj="AU">marchew</towar>
  <towar kraj="PL">pietruszka</towar>
  <towar kraj="PL">pomidor</towar>
  <towar kraj="AU">ziemniaki</towar>
  <towar kraj="PL">seler</towar>
  <towar kraj="US">ziemniaki</towar>
  <towar kraj="US">kalafior</towar>
</root>

Jeśli chcemy pogrupować po atrybucie @kraj możemy zastosować następujący szablon:

<xsl:template match="/root">
<xsl:for-each select="
towar[not(preceding-sibling::towar/@kraj=@kraj)]">


<!-- W tym miejscu następuje operacja na grupie
- np. wypisanie klucza bieżącej grupy -->
Kraj: <xsl:value-of select="@kraj" />&#x0A;

</xsl:for-each>
</xsl:template>

Kluczowym elementem szablonu jest wyrażenie XPath w instrukcji for-each. Za jego pomocą wybierane są wszystkie węzły <towar>, dla których nie istnieje poprzedzający węzeł <towar>, którego atrybut @kraj ma taką samą wartość jak atrybut @kraj aktualnie przetwarzanego węzła.

Powyższa metoda działa jednak wydajność nie jest jej najmocniejszą stroną. O ile można pokusić się o jej zastosowanie w przypadku kilku czy kilkunastu węzłów to raczej nie nadaje się ona jeśli liczba węzłów do przetworzenia jest większa. W takim przypadku zwykle konieczne jest zastosowanie czegoś 'poważniejszego' mianowicie grupowania z zastosowaniem kluczy.