I try to group elements by their headings. My current solution has one disadvantage. The next heading and its content is nested in the body tag of the predecessor. Is it possible to nest only the content in the body tag and not the next group? Has anyone an idea or suggestion? It should look like the example desired result.
Source
<?xml version="1.0" encoding="UTF-8"?>
<html>
<title>headline</title>
<body>
<h1 name="d1e25">H1</h1>
<p>p</p>
<h2 name="d1e25">H2</h2>
<p>p</p>
<h3 name="d1e25">H3</h3>
<p>p</p>
<h3 name="d1e25">H3</h3>
<p>p</p>
<h4 name="d1e25">H4</h4>
<p>p</p>
<h2 name="d1e25">H2</h2>
<table></table>
</body>
</html>
My curent Transformation
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:output method="xml" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:function name="mf:group" as="node()*">
<xsl:param name="elements" as="element()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]">
<xsl:choose>
<xsl:when test="self::*[local-name() eq concat('h', $level)]">
<topic>
<xsl:attribute name="id"><xsl:copy-of select="@name"/></xsl:attribute>
<xsl:element name="title"><xsl:value-of select="." /></xsl:element>
<body>
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</body>
</topic>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/html">
<topic>
<xsl:attribute name="id">
<xsl:attribute name="id" select="generate-id()" />
</xsl:attribute>
<xsl:copy-of select="title"/>
<xsl:apply-templates select="body"/>
</topic>
</xsl:template>
<xsl:template match="body">
<xsl:sequence select="mf:group(*, 1)"/>
</xsl:template>
</xsl:transform>
I get this from the following post grouping following-siblings with same name and same attributes causes exception in saxon
My curent Result
<topic id="d1e1">
<title>headline</title>
<topic id="d1e25">
<title>H1</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H2</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
</body>
</topic>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H4</title>
<body>
<p>p</p>
</body>
</topic>
</body>
</topic>
</body>
</topic>
<topic id="d1e25">
<title>H2</title>
<body>
<table/>
</body>
</topic>
</body>
</topic>
</topic>
Desired Result
<topic id="d1e1">
<title>headline</title>
<topic id="d1e25">
<title>H1</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H2</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
</body>
</topic>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H4</title>
<body>
<p>p</p>
</body>
</topic>
</body>
</topic>
</body>
</topic>
<topic id="d1e25">
<title>H2</title>
<body>
<table/>
</body>
</topic>
</body>
</topic>
</topic>