我能想到的最短的办法是
https://xsltfiddle.liberty-development.net/bFDb2Cz
,它使用带有组合分组键的XSLT 3来测试
w:p
元素及其
@val
一组中的值:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:w="http://example.com/w"
exclude-result-prefixes="xs"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*[w:p[@val]]">
<xsl:copy>
<xsl:for-each-group select="*" composite="yes" group-adjacent="boolean(self::w:p), @val">
<xsl:choose>
<xsl:when test="current-grouping-key()[1]">
<div class="wrapper{current-grouping-key()[2]}">
<xsl:apply-templates select="current-group()"/>
</div>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这个
<xsl:mode on-no-match="shallow-copy"/>
只是一种XSLT 3声明性的方式来表示您想要使用身份转换。
如果在XSLT 2中不能移动到XSLT 3,则需要嵌套两个
xsl:for-each
group-adjacent="boolean(self::w:p)"
,然后在您内部使用一个真正的分组键
xsl:for-each-group select="current-group()" group-adjacent="@val"
group-adjacent="concat((boolean(self::w:p), '|', @val))"
虽然这有点难看,然后在里面检查和提取两个不同的值。
XSLT 2位于
http://xsltransform.hikmatu.com/gWcDMey/1
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:w="http://example.com/w"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[w:p[@val]]">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::w:p)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:for-each-group select="current-group()" group-adjacent="@val">
<div class="wrapper{current-grouping-key()}">
<xsl:apply-templates select="current-group()"/>
</div>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>