I want to wrap groups of elements with a new parent element. Such groups appear in many places in the document. The elements have no attribute.
With for-each-group
I manage to include all desired elements of the document in a large group with a new parent element, but I want to distinguish the groups according to their occurrence. Found many similar questions and answers, but could not solve the problem.
My document
<modul>
<body>
<Standard>some text</Standard>
<Herausforderung>some text</Herausforderung>
<Standard>some text
<d2tb>some text</d2tb>
</Standard>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Standard>some text
<d2ti>some text</d2ti>
</Standard0>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Standard>some text</Standard>
</body>
</modul>
Desired output
<modul>
<body>
<Standard>some text</Standard>
<Herausforderung>some text</Herausforderung>
<Standard>some text
<d2tb>some text</d2tb>
</Standard>
<list>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
</list>
<Standard>some text
<d2ti>some text</d2ti>
</Standard0>
<list>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
</list>
<Standard>some text</Standard>
</body>
</modul>
My XSLT-stylesheet
<xsl:template match="body">
<list>
<xsl:for-each-group select="Aufzhlungbullets" group-by=".">
<xsl:copy-of select="current-group()"/>
</xsl:for-each-group>
</list>
</xsl:template>
note: I know that this template suppresses all other content. At first I concentrated on getting the grouping right. The contents of the rest of the document should of course be visible, but I don't think that's a major problem.
With this template I only get all elements in a large group.
<modul>
<list>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
<Aufzhlungbullets>some text</Aufzhlungbullets>
</list>
</modul>
I tried a lot of variations of my template - without success. How can I differentiate that the wanted elements appear in different groups in the document?
Try using group-adjacent
on the xsl:for-each-group
instead, grouping adjacent nodes by their name, and wrapping the group in a <list>
tag if it it a Aufzhlungbullets
node:
<xsl:template match="body">
<list>
<xsl:for-each-group select="*" group-adjacent="local-name()">
<xsl:choose>
<xsl:when test="self::Aufzhlungbullets">
<list>
<xsl:copy-of select="current-group()" />
</list>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</list>
</xsl:template>