XSLT:将平面列表转化为层次结构 [英] XSLT: turn flat list into hierarchy

查看:38
本文介绍了XSLT:将平面列表转化为层次结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了解 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆