Group slicing in XSLT with parameters

One other twist on the last slicing stylesheet. Let's say that we didn't want to hard-code the number of items in a group, but instead we wanted to be able to control this separately. We can use an xsl:param on the stylesheet to control this externally and provide a default as well.

Here is the touched up stylesheet, with the changes highlighted.

<xsl:stylesheet version='1.0' xmlns:xsl='https://www.w3.org/1999/XSL/Transform'>
 <xsl:output method='xml' indent='yes'/>
 <xsl:param name='itemcount'>2</xsl:param>

 <!-- Just copy everything. -->
 <xsl:template match='@* | node()' mode='everything'>
  <xsl:copy>
   <xsl:apply-templates select='@* | node()' mode='everything'/>
  </xsl:copy>
 </xsl:template>

 <!-- Copy everything but replace items with the replacement parameter. -->
 <xsl:template match='@* | node()' mode='withreplacement'>
  <xsl:param name='replacement' />
  <xsl:copy>
   <!-- Copy everything except item elements. -->
   <xsl:apply-templates select='@* | node()[local-name() != "item"]' mode='withreplacement'>
    <xsl:with-param name='replacement' select='$replacement' />
   </xsl:apply-templates>

   <!-- If this is where items are, apply the replacement node-set. -->
   <xsl:if test='item'>
    <xsl:apply-templates select='$replacement' mode='everything' />
   </xsl:if>
  </xsl:copy>
 </xsl:template>

 <!--
 We matched the first of a slice of items.
 Copy everything from the root, passing the current item
 and its sibling(s) as the replacement.
 -->
 <xsl:template match='item' mode='firstofslice'>
  <xsl:apply-templates select='/group' mode='withreplacement'>
   <xsl:with-param
    name='replacement'
    select='. | following-sibling::item[position() &lt; $itemcount]'
    />
  </xsl:apply-templates>
 </xsl:template>

 <!-- Match to root, and put everything under a single element. -->
 <xsl:template match='/'>
  <root>
   <!-- Grab every second item to create a new group. -->
   <xsl:apply-templates select='group/item[position() mod $itemcount = 1]' mode='firstofslice' />
  </root>
 </xsl:template>
</xsl:stylesheet>

By the way, if you haven't already, check out the comments on the first post for a more efficient variation of the stylesheet.

Enjoy!