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

Subject: Aw:  for-each-group throughout a document
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 25 Sep 2026 15:53:52 -0000
What kind of grouping has to be done for li elements? Wrapping adjacent
ones in some list container?

Am 25.09.26, 17:38 schrieb "rick@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>:

Hi All,

I have a flat XML structure like this that I need to add hierarchy to.

<?xml version="1.0" encoding="UTF-8"?>
<doc>
<h1>Heading 1</h1>
<para>Some text under heading 1</para>
<para>Some text under heading 1</para>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<para>Some text under heading 1</para>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<para>Some text under heading 3</para>
<para>Some text under heading 3</para>
<h4>Heading 4</h4>
<para>Some text under heading 4</para>
<li>list item under heading 4</li>
<li>list item under heading 4</li>
<li>list item under heading 4</li>
</doc>

My current stylesheet gives me this, which is what I want:

<?xml version="1.0" encoding="UTF-8"?>
<concept id="d1e3">
<title>Heading 1</title>
<conbody>
<para>Some text under heading 1</para>
<para>Some text under heading 1</para>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<para>Some text under heading 1</para>
<concept id="d1e28">
<title>Heading 2</title>
<conbody>
         &nbs p;  <concept id="d1e31">
;     <title>Heading 3</title>
         &nbs p;     <conbody>
         &nbs p;        <para>Some text under heading 3</para>
;        <para>Some text under heading 3</para>
;        <concept id="d1e41">
;           <title>Heading 4</title>
         &nbs p;           <conbody>
         &nbs p;            &nb sp; <para>Some text under heading
4</para>
;            &nbs p; <li>list item under heading 4</li>
          & nbsp;             <li>list item under heading 4</li>
          & nbsp;             <li>list item under heading 4</li>
          & nbsp;          </conbody>
         &nb sp;        </concept>
         &nb sp;     </conbody>
         &nb sp;  </concept>
</conbody>
</concept>
</conbody>
</concept>

However, I have <li> elements that need to be grouped as well; they can
appear just about anywhere in the source XML. Is there a generalized
solution where I can address grouping anywhere in my structure? Here is
my current stylesheet.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transf orm"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpa th-functions/math"
exclude-result-prefixes="xs math"
version="3.0" expand-text="yes">

    <xsl:output indent="yes"/>

    <xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>

    <xsl:template match="doc">
<xsl:for-each-group select="*" group-starting-with="h1">
      &n bsp;     <xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</xsl:template>

<xsl:template match="h1" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<xsl:choose>
         & nbsp;      <xsl:when test="not(following-sibling::*[1][self::title])">
 & nbsp;             <conbody>
         &nbs p;            &nb sp; <xsl:for-each-group select="current-group()
except ." group-starting-with="h2">
      &n bsp;            & nbsp;        <xsl:apply-templates select="."
mode="group"/>
         &n bsp;            & nbsp; </xsl:for-each-group>
       &nbs p;            </conbody>
         &nb sp;      </xsl:when>
         &n bsp;      <xsl:otherwise>
        &nbs p;           <xsl:for-each-group select="current-group()
except ." group-starting-with="h2">
      &n bsp;            & nbsp;    <xsl:apply-templates select="."
mode="group"/>
         &n bsp;          </xsl:for-each-group>
       &nbs p;        </xsl:otherwise>
        &nb sp;   </xsl:choose>
</concept>
</xsl:template>

<xsl:template match="h2" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<xsl:choose>
         & nbsp;      <xsl:when test="not(following-sibling::*[1][self::heading3])">
&nbs p;            &nb sp;      <conbody>
         &nbs p;            &nb sp; <xsl:for-each-group select="current-group()
except ." group-starting-with="h3">
      &n bsp;            & nbsp;        <xsl:apply-templates select="."
mode="group"/>
         &n bsp;            & nbsp; </xsl:for-each-group>
       &nbs p;            </conbody>
         &nb sp;      </xsl:when>
         &n bsp;      <xsl:otherwise>
        &nbs p;           <xsl:for-each-group select="current-group()
except ." group-starting-with="h3">
      &n bsp;            & nbsp;    <xsl:apply-templates select="."
mode="group"/>
         &n bsp;          </xsl:for-each-group>
       &nbs p;        </xsl:otherwise>
        &nb sp;   </xsl:choose>
</concept>
</xsl:template>

    <xsl:template match="h3" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<xsl:choose>
         & nbsp;      <xsl:when test="not(following-sibling::*[1][self::h4])">
 &nbs p;            &nb sp;     <conbody>
         &nbs p;            &nb sp; <xsl:for-each-group select="current-group()
except ." group-starting-with="h4">
      &n bsp;            & nbsp;        <xsl:apply-templates select="."
mode="group"/>
         &n bsp;            & nbsp; </xsl:for-each-group>
       &nbs p;            </conbody>
         &nb sp;      </xsl:when>
         &n bsp;      <xsl:otherwise>
        &nbs p;           <xsl:for-each-group select="current-group()
except ." group-starting-with="h4">
      &n bsp;            & nbsp;    <xsl:apply-templates select="."
mode="group"/>
         &n bsp;          </xsl:for-each-group>
       &nbs p;        </xsl:otherwise>
        &nb sp;   </xsl:choose>
</concept>
</xsl:template>

    <xsl:template match="h4" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<conbody>
         &nbs p;      <xsl:apply-templates select="current-group() except
."/>
</conbody>
</concept>
</xsl:template>

    <xsl:template match="*" mode="group">
<xsl:apply-templates select="current-group()"/>
</xsl:template>

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

</xsl:stylesheet>

Thank you for your help.

Rick Quatro

XSL-List info and archiveEasyUnsubscribe (by email) XSL-List info and
archiveEasyUnsubscribe (by email)

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