2012-02-07 110 views
2

我尝试了解XSLT 2.0中的分组函数。我的源文件是XSLT:将扁平列表变成层次结构

<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比一个更深刻,...)的下一节应该是当前的子节点,如果是同一级别,则应该是下一个兄弟节点。

我试过xsl:group-by select="entry" group-by="@level"这给了我一个合理的分组,但我不知道如何打开该部分下来,如果有一个下跌。

another similar question其中规定:“在XSLT 2.0中,使用新的分组函数会相当容易。” - 这可能很容易,但我不明白。

+0

以上运行时,你有或将有可能被无限水平的水平固定数目的? – Chris 2012-02-07 12:46:45

+0

@Chris有一个固定的层数(4)。 – topskip 2012-02-07 12:54:05

回答

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> 
+0

对不起,我只能一劳永逸。真棒。 – topskip 2012-02-07 14:03:56