我在this other one评论了目前的问题:现在更复杂,因为需要再次发生。详细说明:
<root>
<c>cccc</c>
<a gr="g1_1">aaaa</a> <b gr="g1_1">1111</b>
<a gr="g2_1" into="g1_1">bbbb</a> <b gr="g2_1" into="g1_1">56565</b>
<a gr="g3_1" into="g2_1">BB</a> <b gr="g3_1" into="g2_1">55</b>
<a gr="g1_2">xxxx</a> <b gr="g1_2">2222</b>
<a gr="g2_2" into="g1_2">wwww</a> <b gr="g2_2" into="g1_2">3433</b>
</root>
必须由fold
标记括起来,(在XSLT之后):
<root>
<c>cccc</c>
<fold>
<a gr="g1_1">aaaa</a> <b gr="g1_1">1111</b>
<fold><a gr="g2_1" into="g1_1">bbbb</a>
<b gr="g2_1" into="g1_1">56565</b>
<fold><a gr="g3_1" into="g2_1">BB</a>
<b gr="g3_1" into="g2_1">55</b>
</fold>
</fold>
</fold>
<fold>
<a gr="g1_2">xxxx</a> <b gr="g1_2">2222</b>
<fold><a gr="g2_2" into="g1_2">wwww</a>
<b gr="g2_2" into="g1_2">3433</b>
</fold>
</fold>
</root>
备注
该示例具有“用于分组的标签”(@gr
)和用于“超级分组”的标签(@into
指向父组。
@gr
是唯一群组的ID,并且还指示语法为"g" level "_" level-id
的“折叠级别”,因此,如果需要,我们可以为折叠级别添加显式属性...或者可以添加和辅助结构(gdef
作为输入元数据),
<gdef>
<group gr="g1_1" level="1" into=""/>
<group gr="g2_1" level="2" into="g1_1"/>
<group gr="g3_1" level="3" into="g2_1"/>
<group gr="g1_2" level="1" into=""/>
<group gr="g2_2" level="2" into="1_2"/>
</gdef>
等。
答案 0 :(得分:1)
您不需要递归。你只需要小心地将模板应用于兄弟姐妹 下面的代码是您在其他(推荐)问题中对解决方案的改编。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*" />
<xsl:output indent="yes" />
<xsl:key name="key" match="*[@gr]" use="@gr" />
<xsl:template match="*[*/@gr]">
<xsl:copy>
<xsl:apply-templates select="*[not(@into)]"/><!--start by most top-level ones-->
</xsl:copy>
</xsl:template>
<xsl:template match="*[@gr]"/>
<xsl:template match="*[@gr][generate-id() = generate-id(key('key', @gr)[1])]">
<fold>
<xsl:for-each select="key('key', @gr)">
<xsl:call-template name="identity" />
</xsl:for-each>
<xsl:apply-templates select="following-sibling::*[@into = current()/@gr]"/>
</fold>
</xsl:template>
<xsl:template match="node()|@*" name="identity" >
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>