Skip to content
xsl:for-each-group

xsl:for-each-group

Partitions a sequence into groups and executes its body once per group.

<xsl:for-each-group select="employee" group-by="@department">
  ...
</xsl:for-each-group>

Exactly one of group-by, group-adjacent, group-starting-with, or group-ending-with must be present. Inside the body, current-group() returns the items in the current group, and current-grouping-key() returns the key for group-by and group-adjacent groupings. The body runs in the context of the first item of each group.

group-by collects all items with the same key into one group regardless of order. group-adjacent only joins consecutive items with the same key into one group. group-starting-with and group-ending-with use a match pattern to delimit groups.

Attributes

Attribute Description
select XPath expression producing the population to group. Required.
group-by XPath expression producing the grouping key.
group-adjacent XPath expression producing the grouping key; only adjacent items are joined.
group-starting-with Pattern that begins a new group.
group-ending-with Pattern that ends the current group.

Examples

Grouping by department:

<xsl:for-each-group select="employee" group-by="@department">
  <dept name="{current-grouping-key()}">
    <xsl:for-each select="current-group()">
      <emp><xsl:value-of select="@name"/></emp>
    </xsl:for-each>
  </dept>
</xsl:for-each-group>

Adjacent grouping — collapse runs of <text> nodes into paragraphs, keeping <break> nodes alone:

<xsl:for-each-group select="*" group-adjacent="name()">
  <xsl:choose>
    <xsl:when test="current-grouping-key() = 'text'">
      <p><xsl:value-of select="current-group()" separator=" "/></p>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="current-group()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each-group>

group-starting-with — split a flat list of headings and paragraphs into sections:

<xsl:for-each-group select="*" group-starting-with="h1">
  <section>
    <xsl:copy-of select="current-group()"/>
  </section>
</xsl:for-each-group>