Если вы используете XSLT 1, вы можете использовать метод группировки по Мюнхену следующим образом:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="chapter" use="@chapter" match="amendment" />
<xsl:template match="section">
<xsl:copy>
<xsl:apply-templates select="heading | amendment[generate-id() = generate-id(key('chapter',@chapter)[1])]" />
</xsl:copy>
</xsl:template>
<xsl:template match="amendment">
<xsl:element name="chapter">
<xsl:attribute name="num">
<xsl:value-of select="@chapter" />
</xsl:attribute>
<xsl:apply-templates select="key('chapter', @chapter)" mode="withoutchapter"/>
</xsl:element>
</xsl:template>
<xsl:template match="amendment" mode="withoutchapter">
<xsl:copy>
<xsl:apply-templates select="@*[(name() != 'chapter')] | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Здесь есть два «поправочных» шаблона - первый (без режима) вызывается толькошаблон раздела о поправках, которые являются первым появлением дополнения с этой главой.Он создает элемент главы и внутри него вызывает второй шаблон для каждого тега amendment
с этой главой.
Два предостережения здесь;Во-первых, любые поправки без главы будут исключены из выходных данных.
Во-вторых, если между двумя тегами поправок есть заголовок, теги поправок все равно будут сгруппированы, а заголовок появится после группы.
Итак, если вы сделаете (сокращенно для ясности):
<amendment num='1' chapter='1' />
<heading>heading text</heading>
<amendment num='2' chapter='1' />
Будет выведено:
<chapter num='1'>
<amendment num='1' />
<amendment num='2' />
</chapter>
<heading>heading text</heading>