Just for grins I wanted to see if I could rewrite a Muenchian Grouping template in XSLT 1.0 without using <xsl:for-each>
. The XML:
<jobs>
<job>
<year>2012</year>
<position>Mayonnaise Maker, Malden Mayonnaise Manufactory, Malden, MA</position>
</job>
<job>
<year>2012</year>
<position>Twine Twirler, Timmy's Twine, Tyngsboro, MA</position>
</job>
<job>
<year>2013</year>
<position>Bagel Boiler, Bob's Bagels, Boxboro, MA</position>
</job>
</jobs>
Standard Muenchian solution, grouping positions by year:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="this-year" match="job" use="year"/>
<xsl:template match="jobs">
<resume>
<xsl:for-each select="job[count(. | key('this-year', year)[1]) = 1]">
<year y="{year}">
<xsl:for-each select="key('this-year', year)">
<position><xsl:value-of select="position"/></position>
</xsl:for-each>
</year>
</xsl:for-each>
</resume>
</xsl:template>
</xsl:stylesheet>
Result:
<?xml version="1.0"?>
<resume>
<year y="2012">
<position>Mayonnaise Maker, Malden Mayonnaise Manufactory, Malden, MA</position>
<position>Twine Twirler, Timmy's Twine, Tyngsboro, MA</position>
</year>
<year y="2013">
<position>Bagel Boiler, Bob's Bagels, Boxboro, MA</position>
</year>
</resume>
It's easy to get rid of the outer <xsl:for-each>
. This works:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="this-year" match="job" use="year"/>
<xsl:template match="jobs">
<resume>
<xsl:apply-templates select="job[count(. | key('this-year', year)[1]) = 1]"/>
</resume>
</xsl:template>
<xsl:template match="job">
<year y="{year}">
<xsl:for-each select="key('this-year', year)">
<position><xsl:value-of select="position"/></position>
</xsl:for-each>
</year>
</xsl:template>
</xsl:stylesheet>
This, however...
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="this-year" match="job" use="year"/>
<xsl:template match="jobs">
<resume>
<xsl:apply-templates select="job[count(. | key('this-year', year)[1]) = 1]"/>
</resume>
</xsl:template>
<xsl:template match="job">
<year y="{year}">
<xsl:apply-templates select="key('this-year', year)"/>
</year>
</xsl:template>
<xsl:template match="key('this-year', year)">
<position><xsl:value-of select="position"/></position>
</xsl:template>
</xsl:stylesheet>
...does not:
error
xsltCompileIdKeyPattern : Literal expected
compilation error: file no-dice.xsl line 17 element template
xsltCompilePattern : failed to compile 'key('this-year', year)'
<xsl:template match="key('this-year', year)">
is valid but it throws that error. Is there some way to push the processing on that key out to another template? Or some other trick to make this work?