I. この XSLT 2.0 変換:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<section>
<xsl:for-each-group select="*"
group-adjacent="self::amendment and @chapter =(1,2)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<newwrapper>
<xsl:sequence select="current-group()"/>
</newwrapper>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</section>
</xsl:template>
</xsl:stylesheet>
提供された XML ドキュメントに適用した場合:
<section>
<heading>some heading text</heading>
<amendment chapter="1">
<foo/>
</amendment>
<amendment chapter="2">
<bar/>
</amendment>
<amendment chapter="3">
<baz/>
</amendment>
<heading>some heading text</heading>
<amendment chapter="1">
<baz/>
</amendment>
</section>
必要な正しい結果が生成されます。
<section>
<heading>some heading text</heading>
<newwrapper>
<amendment chapter="1">
<foo/>
</amendment>
<amendment chapter="2">
<bar/>
</amendment>
</newwrapper>
<amendment chapter="3">
<baz/>
</amendment>
<heading>some heading text</heading>
<newwrapper>
<amendment chapter="1">
<baz/>
</amendment>
</newwrapper>
</section>
説明:
属性xsl:for-each-group
との適切な使用。group-adjacent
Ⅱ.XSLT 1.0 ソリューション:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kFollowing" match="amendment[not(@chapter >2)]" use=
"generate-id(preceding-sibling::*
[not(self::amendment and @chapter <= 2)][1])"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[not(self::amendment and @chapter <= 2)
and
following-sibling::*[1][self::amendment and not(@chapter >2)]
]">
<xsl:call-template name="identity"/>
<newwrapper>
<xsl:apply-templates mode="inGroup"
select="key('kFollowing', generate-id())"/>
</newwrapper>
</xsl:template>
<xsl:template match="*" mode="inGroup">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="amendment[not(@chapter >2)]"/>
</xsl:stylesheet>
この変換が同じ XML ドキュメント (上記) に適用されると、同じ正しい結果が生成されます。
説明:
以下の適切な使用:
ID ルールの利用とオーバーライド。
そのグループの直前の兄弟要素の関数として、属性が より大きくない隣接amendment
要素のグループを定義するためのキー。chapter
2
generate-id()