尝试使用XSLT 2.0转换XML。
Flat Source XML:
<body>
<R1/>
<R1/>
<R2/>
<R2/>
<R2/>
<R3/>
<R3/>
<R3/>
<R1/>
<R1/>
<R2/>
<R2/>
<R1/>
</body>
期望的输出:
<body>
<R1/>
<R1>
<R2/>
<R2/>
<R2>
<R3/>
<R3/>
<R3/>
</R2>
</R1>
<R1/>
<R1>
<R2/>
<R2/>
</R1>
<R1/>
</body>
基本上这些R1-R3元素表示sect-1,sect-2,sect-3类型元素。 R2嵌套在它们之前的兄弟R1中,R3嵌套在它们之前的兄弟R2中。相同的元素在同一级别上。
答案 0 :(得分:2)
使用for-each-group-starting-with:
<?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:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:param name="prefix" as="xs:string" select="'R'"/>
<xsl:output indent="yes"/>
<xsl:function name="mf:group" as="element()*">
<xsl:param name="elements" as="element()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$elements" group-starting-with="*[local-name() = concat($prefix, $level)]">
<xsl:element name="{name()}">
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</xsl:element>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="body">
<xsl:copy>
<xsl:sequence select="mf:group(*, 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>