XSLT:将平面列表转化为层次结构 [英] XSLT: turn flat list into hierarchy
问题描述
我尝试了解 XSLT 2.0 中的分组功能.我的源文件是
I try to understand the grouping functions in XSLT 2.0. My source document is
<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更深,...),下一个section应该是当前的child,如果是同一个level,应该是下一个兄弟.
That is: if there is a following entry with a deeper level (b is deeper than a,...) the next section should be child of the current, if it is the same level, it should be the next sibling.
我试过 xsl:group-by select="entry" group-by="@level"
这给了我一个合理的分组,但我不知道如何打开部分下降,如果有下降.
I've tried with xsl:group-by select="entry" group-by="@level"
which gives me a sensible grouping, but I don't know how to open the section to go down, if there is a down.
还有 另一个类似的问题 指出在 XSLT 2.0 中,使用新的分组功能会很容易".- 这可能很容易,但我不明白.
There is another similar question which states that "In XSLT 2.0 it would be rather easy with the new grouping functions." - it might be easy but I don't get it.
推荐答案
这是一个例子:
<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"的任何级别.
Should work with any levels from 'a' to 'z'.
Saxon 9.4,在上面运行时
Saxon 9.4, when running above against
<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>
这篇关于XSLT:将平面列表转化为层次结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!