[Home] [By Thread] [By Date] [Recent Entries]

Subject: Re: for-each-group throughout a document
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 25 Sep 2026 23:44:04 -0000
On 25/09/2026 18:05, rick@xxxxxxxxxxxxxx wrote:
>
> Yes, wrapping them like this:
>
> B B B B B  <ul>
> B B B B B B B B  <li>list item under heading 1</li>
> B B B B B B B B  <li>list item under heading 1</li>
> B B B B B B B B  <li>list item under heading 1</li>
> B B B B B B B B  <li>list item under heading 1</li>
> B B B B B  </ul>
>
>
>
>
There is some stuff in the existing, posted XSLT that doesn't seem to
relate to the posted XML input, e.g. there are tests for stuff like
<xsl:when test="not(following-sibling::*[1][self::heading3])"> where
"heading3" didn't exist at all in the input or tests like <xsl:when
test="not(following-sibling::*[1][self::title])"> where there are no
"title" elements. So ignoring these tests I wonder whether a recursive
grouping on h1, h2, ... suffices that then, once grouping on hx elements
is exhausted, also does a grouping on adjacent li elements:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 B  version="3.0"
 B  xmlns:xs="http://www.w3.org/2001/XMLSchema"
 B  xmlns:mf="http://example.com/mf"
 B  exclude-result-prefixes="#all"
 B  expand-text="yes">

 B  <xsl:output method="xml" indent="yes"/>

 B  <xsl:mode on-no-match="shallow-copy"/>

 B  <xsl:function name="mf:group" as="node()*">
 B  B  <xsl:param name="elements" as="element()*"/>
 B  B  <xsl:sequence select="mf:group($elements, 1)"/>
 B  </xsl:function>

 B  <xsl:function name="mf:group" as="node()*">
 B  B  <xsl:param name="elements" as="element()*"/>
 B  B  <xsl:param name="level" as="xs:integer"/>
 B  B  <xsl:for-each-group select="$elements"
group-starting-with="*[local-name() = 'h' || $level]">
 B  B  B  <xsl:choose>
 B  B  B  B  <xsl:when test="self::*[local-name() = 'h' || $level]">
 B  B  B  B  B  <concept id="{generate-id()}">
 B  B  B  B  B  B  <title>
 B  B  B  B  B  B  B  <xsl:apply-templates/>
 B  B  B  B  B  B  </title>
 B  B  B  B  B  B  <conbody>
 B  B  B  B  B  B  B  <xsl:sequence select="mf:group(current-group() except .,
$level + 1)"/>
 B  B  B  B  B  B  </conbody>
 B  B  B  B  B  </concept>
 B  B  B  B  </xsl:when>
 B  B  B  B  <xsl:otherwise>
 B  B  B  B  B  <xsl:for-each-group select="current-group()"
group-adjacent=". instance of element(li)">
 B  B  B  B  B  B  <xsl:choose>
 B  B  B  B  B  B  B  <xsl:when test="current-grouping-key()">
 B  B  B  B  B  B  B  B  <ul>
 B  B  B  B  B  B  B  B  B  <xsl:apply-templates select="current-group()"/>
 B  B  B  B  B  B  B  B  </ul>
 B  B  B  B  B  B  B  </xsl:when>
 B  B  B  B  B  B  B  <xsl:otherwise>
 B  B  B  B  B  B  B  B  <xsl:apply-templates select="current-group()"/>
 B  B  B  B  B  B  B  </xsl:otherwise>
 B  B  B  B  B  B  </xsl:choose>
 B  B  B  B  B  </xsl:for-each-group>
 B  B  B  B  </xsl:otherwise>
 B  B  B  </xsl:choose>
 B  B  </xsl:for-each-group>
 B  </xsl:function>

 B  <xsl:template match="doc">
 B  B  <xsl:sequence select="mf:group(*)"/>
 B  </xsl:template>

</xsl:stylesheet>

Current Thread
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member