Если вы используете процессор XSLT 3, такой как Saxon 9.8 или более поздней версии или Altova XML 2017 R3 или более поздней версии, вы можете использовать составной ключ группировки элементов, которые вы хотите использовать в качестве ключа группировки, тогда, конечно, внутри вас необходимо убедиться, что вы создаете один row
для каждой группы и обрабатываете элементы, образующие ключ группировки, только один раз (например, для первого элемента в группе, который является контекстным элементом внутри for-each-group
), а затем для всех остальных элементы для всех элементов в группе:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="row" composite="yes" group-by="col1, col2, col3, col4, col5">
<xsl:copy>
<xsl:apply-templates select="col1, col2, col3, col4, col5, current-group()/(* except (col1, col2, col3, col4, col5))"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jz1Q1yt
Или, возможно, тело for-each-group
немного менее повторяется в терминах ключевых элементов группировки с
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="row!copy-of()" composite="yes" group-by="col1, col2, col3, col4, col5">
<xsl:copy>
<xsl:apply-templates select="current-group()/(if (position() eq 1) then * else (* except (col1, col2, col3, col4, col5)))"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/jz1Q1yt/1