与标准的Meunchain分组略有不同,因为我正在处理我正在转换的某些标记的null(?)属性。我希望将空分组视为它们自己的单独组,其中转换后的输出添加了分组字符串。此外,如果有一个分组来计算有多少。
<root>
<section>
<subsection>
<module>
<comp>111</comp>
</module>
<module group='group01'>
<comp>222</comp>
</module>
<module group='group01'>
<comp>333</comp>
</module>
<module>
<comp>444</comp>
</module>
<module>
<comp>555</comp>
</module>
</subsection>
</section>
<section>
<subsection>
<module group ="group02">
<comp>666</comp>
</module>
<module group ="group02">
<comp>777</comp>
</module>
<module>
<comp>888</comp>
</module>
<module group ="group03">
<comp>999</comp>
</module>
<module group ="group03">
<comp>101010</comp>
</module>
</subsection>
<subsection>
<module group ="group04">
<comp>11111</comp>
</module>
<module group ="group04">
<comp>121212</comp>
</module>
<module group ="group05">
<comp>131313</comp>
</module>
<module group ="group05">
<comp>141414</comp>
</module>
<module group ="group06">
<comp>151515</comp>
</module>
<module group ="group06">
<comp>161616</comp>
</module>
<module>
<comp>171717</comp>
</module>
</subsection>
</section>
通缉输出:
<AllSections>
<section>
<subsection>
<page>
<content>111</content>
</page>
<page>
<content>222333</content>
<count>2</count>
</page>
<page>
<content>444</content>
</page>
<page>
<content>555</content>
</page>
</subsection>
</section>
<section>
<subsection>
<page>
<content>666777</content>
<count>2</count>
</page>
<page>
<content>888</content>
</page>
<page>
<content>999101010</content>
<count>2</count>
</page>
</subsection>
<subsection>
<page>
<content>111111121212</content>
<count>2</count>
</page>
<page>
<content>131313141414161616</content>
<count>3</count>
</page>
<page>
<content>151515</content>
</page>
<page>
<content>171717</content>
</page>
</subsection>
</section>
谢谢!
答案 0 :(得分:2)
对于具有组属性的元素,您按该属性进行分组,但也在父子部分元素内进行分组。因此,您可以从定义一个键来开始,这是
<xsl:key name="modules" match="module[@group]" use="concat(generate-id(..), '|', @group)" />
接下来,您需要模板来匹配模块元素的各种情况。首先,您可以使用模板来匹配模块元素,而不使用组属性,您可以根据需要格式化输出。
<xsl:template match="module[not(@group)]">
<page>
<content>
<xsl:value-of select="comp"/>
</content>
</page>
</xsl:template>
对于具有组属性的模块,您需要一个匹配项,以检查此特定模块元素是否首先出现在上面定义的键的组中。
<xsl:template
match="module
[@group]
[generate-id() = generate-id(key('modules', concat(generate-id(..), '|', @group))[1])]">
在此模板中,您可以轻松定义变量以使用键保存组中的元素,然后输出子 comp 元素或计算它们
<xsl:variable name="modules" select="key('modules', concat(generate-id(..), '|', @group))"/>
<page>
<content>
<xsl:apply-templates select="$modules/comp/text()"/>
</content>
<count>
<xsl:value-of select="count($modules)" />
</count>
</page>
最后,您需要第三个模板来匹配所有其他模块元素(即具有组属性的元素,但不是组中的第一个元素)来忽略它们,确保他们不会得到两次输出。 (在更通用的模板之前,XSLT处理器应始终匹配更具体的模板)
<xsl:template match="module"/>
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="modules" match="module[@group]" use="concat(generate-id(..), '|', @group)"/>
<xsl:template match="root">
<AllSections>
<xsl:apply-templates />
</AllSections>
</xsl:template>
<xsl:template match="module[not(@group)]">
<page>
<content>
<xsl:value-of select="comp"/>
</content>
</page>
</xsl:template>
<xsl:template match="module[@group][generate-id() = generate-id(key('modules', concat(generate-id(..), '|', @group))[1])]">
<xsl:variable name="modules" select="key('modules', concat(generate-id(..), '|', @group))"/>
<page>
<content>
<xsl:apply-templates select="$modules/comp/text()"/>
</content>
<count>
<xsl:value-of select="count($modules)" />
</count>
</page>
</xsl:template>
<xsl:template match="module"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<AllSections>
<section>
<subsection>
<page>
<content>111</content>
</page>
<page>
<content>222333</content>
<count>2</count>
</page>
<page>
<content>444</content>
</page>
<page>
<content>555</content>
</page>
</subsection>
</section>
<section>
<subsection>
<page>
<content>666777</content>
<count>2</count>
</page>
<page>
<content>888</content>
</page>
<page>
<content>999101010</content>
<count>2</count>
</page>
</subsection>
<subsection>
<page>
<content>11111121212</content>
<count>2</count>
</page>
<page>
<content>131313141414</content>
<count>2</count>
</page>
<page>
<content>151515161616</content>
<count>2</count>
</page>
<page>
<content>171717</content>
</page>
</subsection>
</section>
</AllSections>