这种分组可以通过一种称为“兄弟递归”的方法来实现,对于您的问题,我建议使用如下样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/groupme[not(preceding-sibling::*[1][self::groupme])]">
<xsl:copy>
<xsl:apply-templates select="node()"/>
<xsl:apply-templates select="following-sibling::*[1][self::groupme][1]" mode="list"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]"/>
<xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]" mode="list">
<xsl:text> </xsl:text>
<xsl:apply-templates select="node()"/>
<xsl:apply-templates select="following-sibling::*[1][self::groupme][1]" mode="list"/>
</xsl:template>
</xsl:stylesheet>
当应用于输入时
<root>
<a>foo</a>
<b>bar</b>
<groupme>foobar</groupme>
<groupme>baz</groupme>
<groupme>42</groupme>
<c>abc</c>
<d>def</d>
<groupme>foo</groupme>
<x>xyz</x>
<groupme>bar</groupme>
<groupme>foo</groupme>
<z>thats it</z>
</root>
结果是
<root>
<a>foo</a>
<b>bar</b>
<groupme>foobar baz 42</groupme>
<c>abc</c>
<d>def</d>
<groupme>foo</groupme>
<x>xyz</x>
<groupme>bar foo</groupme>
<z>thats it</z>
</root>
作为兄弟递归的替代方案,还可以使用基于键的方法“抓取”以下兄弟:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:key
name="first"
match="root/groupme[preceding-sibling::*[1][self::groupme]]"
use="generate-id(preceding-sibling::groupme[not(preceding-sibling::*[1][self::groupme])][1])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/groupme[not(preceding-sibling::*[1][self::groupme])]">
<xsl:copy>
<xsl:apply-templates select="node()"/>
<xsl:apply-templates select="key('first', generate-id())" mode="list"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]"/>
<xsl:template match="root/groupme" mode="list">
<xsl:text> </xsl:text>
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>