我尝试理解XSLT 2.0中的分组功能。我的源文件是
<root>
<entry level="a" name="aaa"/>
<entry level="a" name="bbb"/>
<entry level="b" name="ccc"/>
<entry level="c" name="ddd"/>
<entry level="a" name="eee"/>
<entry level="a" name="fff"/>
<entry level="b" name="ggg"/>
</root>
,结果应该是
<section name="aaa"/>
<section name="bbb">
<section name="ccc">
<section name="ddd" />
</section>
</section>
<section name="eee"/>
<section name="fff">
<section name="ggg" />
</section>
那就是:如果有一个更深层次的后续条目(b比a更深,......),下一节应该是当前的子节点,如果它是同一级别,它应该是下一个兄弟节点
我尝试使用xsl:group-by select="entry" group-by="@level"
给了我一个明智的分组,但我不知道如果有一个失败,如何打开该部分。
有another similar question表明“在XSLT 2.0中,使用新的分组功能会相当容易。” - 这可能很容易,但我不明白。
答案 0 :(得分:3)
以下是一个例子:
<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:output indent="yes"/>
<xsl:function name="mf:group" as="element(section)*">
<xsl:param name="entries" as="element(entry)*"/>
<xsl:param name="level" as="xs:string"/>
<xsl:for-each-group select="$entries" group-starting-with="entry[@level = $level]">
<section name="{@name}">
<xsl:sequence select="mf:group(current-group() except ., codepoints-to-string(string-to-codepoints($level)[1] + 1))"/>
</section>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="root">
<xsl:copy>
<xsl:sequence select="mf:group(entry, 'a')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应该使用从'a'到'z'的任何级别。
撒克逊人9.4,在上面跑时
<root>
<entry level="a" name="aaa"/>
<entry level="a" name="bbb"/>
<entry level="b" name="ccc"/>
<entry level="c" name="ddd"/>
<entry level="a" name="eee"/>
<entry level="a" name="fff"/>
<entry level="b" name="ggg"/>
</root>
输出
<root>
<section name="aaa"/>
<section name="bbb">
<section name="ccc">
<section name="ddd"/>
</section>
</section>
<section name="eee"/>
<section name="fff">
<section name="ggg"/>
</section>
</root>