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

Subject: Re:   for-each-group throughout a document
From: "rick@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 25 Sep 2026 16:05:15 -0000
Yes, wrapping them like this:



      <ul>
         <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>
      </ul>



Thank you.



From: Martin Honnen martin.honnen@xxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Friday, September 25, 2026 11:54 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Aw:  for-each-group throughout a document



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 <http://rickquatro.com> "
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx <http://lists.mulberrytech.com> >:

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>
            <concept id="d1e31">
               <title>Heading 3</title>
               <conbody>
                  <para>Some text under heading 3</para>
                  <para>Some text under heading 3</para>
                  <concept id="d1e41">
                     <title>Heading 4</title>
                     <conbody>
                        <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>
                     </conbody>
                  </concept>
               </conbody>
            </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/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-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">
            <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>
                <xsl:when test="not(following-sibling::*[1][self::title])">
                    <conbody>
                        <xsl:for-each-group select="current-group() except ."
group-starting-with="h2">
                            <xsl:apply-templates select="." mode="group"/>
                        </xsl:for-each-group>
                    </conbody>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:for-each-group select="current-group() except ."
group-starting-with="h2">
                        <xsl:apply-templates select="." mode="group"/>
                    </xsl:for-each-group>
                </xsl:otherwise>
            </xsl:choose>
        </concept>
    </xsl:template>

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

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

    <xsl:template match="h4" mode="group">
        <concept id="{generate-id()}">
            <title><xsl:apply-templates/></title>
            <conbody>
                <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 archive <http://www.mulberrytech.com/xsl/xsl-list>

EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/582271>  (by
email)

XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>

EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/612310>  (by
email <> )

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