<!-- FasterGrouping.xsl: Leverage XSLT key's like database indexes --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <!-- | Use xsl:key to create index on the "dev" value in /open-bugs/bug nodeset | This is conceptually similar to: | CREATE INDEX dev-index ON /open-bugs/bug ( dev ) in a SQL-like Syntax +--> <xsl:key name="dev-index" match="/open-bugs/bug" use="dev"/> <xsl:template match="/"> <BugsByDeveloper> <!-- | Select all unique developer names by selecting the | first node indexed by the XSLT key for the current value of <dev> +--> <xsl:for-each select="/open-bugs/bug/dev[generate-id(.)= generate-id(key('dev-index',.)[1]/dev)]"> <!-- Sort by the value of dev, the current node "." --> <xsl:sort select="."/> <BugList for="{.}"> <!-- | Select and copy all bugs for the current developer. | Given the dev name, the key('dev-index',.) returns | the nodeset of all his bugs. +--> <xsl:for-each select="key('dev-index',.)"> <!-- Copy the current <bug> node --> <xsl:copy> <!-- Including children <id>,<abstract>,<priority> --> <xsl:copy-of select="id|abstract|priority"/> </xsl:copy> </xsl:for-each> </BugList> </xsl:for-each> </BugsByDeveloper> </xsl:template> </xsl:stylesheet> |