HTML 列表 - XSLT 每个循环多个嵌套

发布于 2025-01-01 11:40:16 字数 3566 浏览 4 评论 0原文

我正在尝试从 xml/xsl 生成多级嵌套 html 列表。

例如,首选的 html 输出将是:

<ul>
 <li>Level 1 - Item 1</li>
    <ul>
        <li>Level 2 - Item 1-1</li>
        <li>Level 2 - Item 1-2</li>
    </ul>

<li> Level 1 - Item 2</li>
    <ul>
        <li>Level 2 - Item 2-1
            <ul>
                <li>Level 3 - Item 2-1-1</li>
                <li>Level 3 - Item 2-1-2</li>
                <li>Level 3 - Item 2-1-3</li>
            </ul>
        </li>
        <li>Level 2 - Item 2-2
            <ul>
                <li>Level 3 - Item 2-2-1</li>
                <li>Level 3 - Item 2-2-2</li>
            </ul>
        </li>
</ul>

XML:

<doc>

    <item>
        <one>Level 1 - Item 1</one>
            <two>Level 2 - Item 1-1</two>
            <two>Level 2 - Item 1-2</two>
    </item>

    <item>
        <one>Level 2 - Item 2</one>
            <two>Level 2 - Item 2-1</two>
                <three>Level 3 - Item 2-1-1</three>
                <three>Level 3 - Item 2-1-2</three>
                <three>Level 3 - Item 2-1-3</three>
            <two>Level 2 - Item 2-2</two>
                <three>Level 3 - Item 2-2-1</three>
                <three>Level 3 - Item 2-2-2</three> 
    </item>

</doc>

我糟糕的尝试 XSL:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
    <html>
    <body>
    <xsl:for-each select="doc/item">
    <li><xsl:value-of select="one" />
    <ul>
    <xsl:for-each select="two">
    <li><xsl:value-of select="."/>
    <xsl:for-each select="../three"><ul><li><xsl:value-of select="."/></li></ul></xsl:for-each>
    </li>
    </xsl:for-each>
    </ul>
    </li>
    </xsl:for-each>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>

这就是我在下面得到的内容... 请注意,当存在 3 级项目时,所有项目都会合并,然后显示在两者之下。

    <li>Level 1 - Item 1<ul>
    <li>Level 2 - Item 1-1</li>
    <li>Level 2 - Item 1-2</li>
    </ul>
    </li>
    <li>Level 2 - Item 2<ul>
    <li>Level 2 - Item 2-1<ul>
    <li>Level 3 - Item 2-1-1</li>
    </ul>

    <ul>
    <li>Level 3 - Item 2-1-2</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-1-3</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-2-1</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-2-2</li>
    </ul>
    </li>

    <li>Level 2 - Item 2-2<ul>
    <li>Level 3 - Item 2-1-1</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-1-2</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-1-3</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-2-1</li>
    </ul>

    <ul>
    <li>Level 3 - Item 2-2-2</li>
    </ul>
    </li>
    </ul>
    </li>

请向我提供 1.0 解决方案,然后当然也展示 2.0 示例以帮助其他人。

谢谢你!

I'm trying to generate a multi level nested html list from xml/xsl.

For example, a preferred html output would be:

<ul>
 <li>Level 1 - Item 1</li>
    <ul>
        <li>Level 2 - Item 1-1</li>
        <li>Level 2 - Item 1-2</li>
    </ul>

<li> Level 1 - Item 2</li>
    <ul>
        <li>Level 2 - Item 2-1
            <ul>
                <li>Level 3 - Item 2-1-1</li>
                <li>Level 3 - Item 2-1-2</li>
                <li>Level 3 - Item 2-1-3</li>
            </ul>
        </li>
        <li>Level 2 - Item 2-2
            <ul>
                <li>Level 3 - Item 2-2-1</li>
                <li>Level 3 - Item 2-2-2</li>
            </ul>
        </li>
</ul>

XML:

<doc>

    <item>
        <one>Level 1 - Item 1</one>
            <two>Level 2 - Item 1-1</two>
            <two>Level 2 - Item 1-2</two>
    </item>

    <item>
        <one>Level 2 - Item 2</one>
            <two>Level 2 - Item 2-1</two>
                <three>Level 3 - Item 2-1-1</three>
                <three>Level 3 - Item 2-1-2</three>
                <three>Level 3 - Item 2-1-3</three>
            <two>Level 2 - Item 2-2</two>
                <three>Level 3 - Item 2-2-1</three>
                <three>Level 3 - Item 2-2-2</three> 
    </item>

</doc>

My poor attempt XSL:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
    <html>
    <body>
    <xsl:for-each select="doc/item">
    <li><xsl:value-of select="one" />
    <ul>
    <xsl:for-each select="two">
    <li><xsl:value-of select="."/>
    <xsl:for-each select="../three"><ul><li><xsl:value-of select="."/></li></ul></xsl:for-each>
    </li>
    </xsl:for-each>
    </ul>
    </li>
    </xsl:for-each>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>

This is what I'm getting below... Notice that when there's a level 3 item then all of items have merged and then displaying under both.

    <li>Level 1 - Item 1<ul>
    <li>Level 2 - Item 1-1</li>
    <li>Level 2 - Item 1-2</li>
    </ul>
    </li>
    <li>Level 2 - Item 2<ul>
    <li>Level 2 - Item 2-1<ul>
    <li>Level 3 - Item 2-1-1</li>
    </ul>

    <ul>
    <li>Level 3 - Item 2-1-2</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-1-3</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-2-1</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-2-2</li>
    </ul>
    </li>

    <li>Level 2 - Item 2-2<ul>
    <li>Level 3 - Item 2-1-1</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-1-2</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-1-3</li>
    </ul>
    <ul>
    <li>Level 3 - Item 2-2-1</li>
    </ul>

    <ul>
    <li>Level 3 - Item 2-2-2</li>
    </ul>
    </li>
    </ul>
    </li>

Please provide me with 1.0 solutions and then of course show 2.0 examples to help others as well.

thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情泪▽动烟 2025-01-08 11:40:16

这是一个适用于您的输入 XML 的 XSLT 1.0 解决方案。

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:my="http://tempuri.org"
  exclude-result-prefixes="my"
>
  <xsl:output indent="yes" />

  <!-- define which elements are where in the hierarchy -->
  <my:level name="one"   higher="" deeper="two,three" />
  <my:level name="two"   higher="one" deeper="three"  />
  <my:level name="three" higher="one,two" deeper="" />

  <xsl:template match="doc">
    <body>
      <xsl:apply-templates mode="ul" select="item/*[1]" />
    </body>
  </xsl:template>

  <xsl:template match="one|two|three" mode="ul">
    <ul>
      <xsl:apply-templates mode="li" select="." />
    </ul>
  </xsl:template>

  <xsl:template match="one|two|three" mode="li">
    <xsl:variable name="myName" select="name()" />
    <xsl:variable name="myID"   select="generate-id()" />
    <!-- select the appropriate hierarchy info for this node -->
    <xsl:variable name="level"  select="
      document('')/*/my:level[@name = $myName]
    " />
    <li>
      <xsl:value-of select="." />
      <!-- create <ul> if immediately follwing sibling is deeper -->
      <xsl:apply-templates mode="ul" select="
        following-sibling::*[1][contains($level/@deeper, name())]
      " />
    </li>
    <!-- process contiguous following siblings of same level -->
    <xsl:apply-templates mode="li" select="
      following-sibling::*[name() = $myName][
        generate-id(
          preceding-sibling::*[contains($level/@higher, name())][1]/following-sibling::*[1]
        ) 
        = $myID
      ]
    " />
  </xsl:template>

</xsl:stylesheet>

给定您问题中的输入文档,它会产生以下输出:

<body>
  <ul>
    <li>Level 1 - Item 1
      <ul>
        <li>Level 2 - Item 1-1</li>
        <li>Level 2 - Item 1-2</li>
      </ul>
    </li>
  </ul>
  <ul>
    <li>Level 2 - Item 2
      <ul>
        <li>Level 2 - Item 2-1
          <ul>
            <li>Level 3 - Item 2-1-1</li>
            <li>Level 3 - Item 2-1-2</li>
            <li>Level 3 - Item 2-1-3</li>
          </ul>
        </li>
        <li>Level 2 - Item 2-2
          <ul>
            <li>Level 3 - Item 2-2-1</li>
            <li>Level 3 - Item 2-2-2</li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</body>

坦率地说,我现在太累了,无法详细解释解决方案。不过我留下了一些评论。可以说它相当复杂。

如果您的 XML 如下所示(即正确嵌套):

<doc>
  <item title="Level 1 - Item 1">
    <item title="Level 2 - Item 1-1" />
    <item title="Level 2 - Item 1-2" />
  </item>
  <item title="Level 2 - Item 2">
    <item title="Level 2 - Item 2-1">
      <item title="Level 3 - Item 2-1-1" />
      <item title="Level 3 - Item 2-1-2" />
      <item title="Level 3 - Item 2-1-3" />
    </item>
    <item title="Level 2 - Item 2-2">
      <item title="Level 3 - Item 2-2-1" />
      <item title="Level 3 - Item 2-2-2" />
    </item>
  </item>
</doc>

生成与上面相同的 HTML 结果的解决方案将如下所示:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output indent="yes" />

  <xsl:template match="doc">
    <body>
      <xsl:for-each select="item">
        <ul>
          <xsl:apply-templates select="." />
        </ul>
      </xsl:for-each>
    </body>
  </xsl:template>

  <xsl:template match="item">
    <li>
      <xsl:value-of select="@title" />
      <xsl:if test="item">
        <ul>
          <xsl:apply-templates select="item" />
        </ul>
      </xsl:if>
    </li>
  </xsl:template>
</xsl:stylesheet>

Here is an XSLT 1.0 solution that works with your input XML.

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:my="http://tempuri.org"
  exclude-result-prefixes="my"
>
  <xsl:output indent="yes" />

  <!-- define which elements are where in the hierarchy -->
  <my:level name="one"   higher="" deeper="two,three" />
  <my:level name="two"   higher="one" deeper="three"  />
  <my:level name="three" higher="one,two" deeper="" />

  <xsl:template match="doc">
    <body>
      <xsl:apply-templates mode="ul" select="item/*[1]" />
    </body>
  </xsl:template>

  <xsl:template match="one|two|three" mode="ul">
    <ul>
      <xsl:apply-templates mode="li" select="." />
    </ul>
  </xsl:template>

  <xsl:template match="one|two|three" mode="li">
    <xsl:variable name="myName" select="name()" />
    <xsl:variable name="myID"   select="generate-id()" />
    <!-- select the appropriate hierarchy info for this node -->
    <xsl:variable name="level"  select="
      document('')/*/my:level[@name = $myName]
    " />
    <li>
      <xsl:value-of select="." />
      <!-- create <ul> if immediately follwing sibling is deeper -->
      <xsl:apply-templates mode="ul" select="
        following-sibling::*[1][contains($level/@deeper, name())]
      " />
    </li>
    <!-- process contiguous following siblings of same level -->
    <xsl:apply-templates mode="li" select="
      following-sibling::*[name() = $myName][
        generate-id(
          preceding-sibling::*[contains($level/@higher, name())][1]/following-sibling::*[1]
        ) 
        = $myID
      ]
    " />
  </xsl:template>

</xsl:stylesheet>

Given the input document from your question, it produces this output:

<body>
  <ul>
    <li>Level 1 - Item 1
      <ul>
        <li>Level 2 - Item 1-1</li>
        <li>Level 2 - Item 1-2</li>
      </ul>
    </li>
  </ul>
  <ul>
    <li>Level 2 - Item 2
      <ul>
        <li>Level 2 - Item 2-1
          <ul>
            <li>Level 3 - Item 2-1-1</li>
            <li>Level 3 - Item 2-1-2</li>
            <li>Level 3 - Item 2-1-3</li>
          </ul>
        </li>
        <li>Level 2 - Item 2-2
          <ul>
            <li>Level 3 - Item 2-2-1</li>
            <li>Level 3 - Item 2-2-2</li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</body>

Frankly, I'm too tired right now to explain the solution in detail. I've left a few comments though. Suffice it to say that it is pretty complicated.

If your XML would look like this (i.e. properly nested):

<doc>
  <item title="Level 1 - Item 1">
    <item title="Level 2 - Item 1-1" />
    <item title="Level 2 - Item 1-2" />
  </item>
  <item title="Level 2 - Item 2">
    <item title="Level 2 - Item 2-1">
      <item title="Level 3 - Item 2-1-1" />
      <item title="Level 3 - Item 2-1-2" />
      <item title="Level 3 - Item 2-1-3" />
    </item>
    <item title="Level 2 - Item 2-2">
      <item title="Level 3 - Item 2-2-1" />
      <item title="Level 3 - Item 2-2-2" />
    </item>
  </item>
</doc>

a solution that would produce the same HTML result as above would look like this:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output indent="yes" />

  <xsl:template match="doc">
    <body>
      <xsl:for-each select="item">
        <ul>
          <xsl:apply-templates select="." />
        </ul>
      </xsl:for-each>
    </body>
  </xsl:template>

  <xsl:template match="item">
    <li>
      <xsl:value-of select="@title" />
      <xsl:if test="item">
        <ul>
          <xsl:apply-templates select="item" />
        </ul>
      </xsl:if>
    </li>
  </xsl:template>
</xsl:stylesheet>
原来是傀儡 2025-01-08 11:40:16

尝试下面的方法。
说明:选择前面具有相同第一个“两个”同级的所有“三个”同级。
我在 XML Spy 中运行它并获得了想要的输出(参见下面的 xslt)。

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <html>
            <body>
                <xsl:for-each select="doc/item">
                    <li>
                        <xsl:value-of select="one" />
                        <ul>
                            <xsl:for-each select="two">
                                <li>
                                    <xsl:value-of select="."/>
                                    <ul>
                                        <xsl:for-each select="following-sibling::three[preceding-sibling::two[1]=current()]">
                                                <li>
                                                    <xsl:value-of select="."/>
                                                </li>
                                        </xsl:for-each>
                                    </ul>
                                </li>
                            </xsl:for-each>
                        </ul>
                    </li>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
    </xsl:stylesheet>

输出:

<html>
    <body>
        <li>Level 1 - Item 1
            <ul>
                <li>Level 2 - Item 1-1
                    <ul></ul>
                </li>
                <li>Level 2 - Item 1-2
                    <ul></ul>
                </li>
            </ul>
        </li>
        <li>Level 2 - Item 2
            <ul>
                <li>Level 2 - Item 2-1
                    <ul>
                        <li>Level 3 - Item 2-1-1</li>
                        <li>Level 3 - Item 2-1-2</li>
                        <li>Level 3 - Item 2-1-3</li>
                    </ul>
                </li>
                <li>Level 2 - Item 2-2
                    <ul>
                        <li>Level 3 - Item 2-2-1</li>
                        <li>Level 3 - Item 2-2-2</li>
                    </ul>
                </li>
            </ul>
        </li>
    </body>
</html>

Try the below.
Explanation: select all "three" siblings that have the same first "two" sibling preceding it.
I ran this in XML Spy and got the wanted output (see below xslt).

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <html>
            <body>
                <xsl:for-each select="doc/item">
                    <li>
                        <xsl:value-of select="one" />
                        <ul>
                            <xsl:for-each select="two">
                                <li>
                                    <xsl:value-of select="."/>
                                    <ul>
                                        <xsl:for-each select="following-sibling::three[preceding-sibling::two[1]=current()]">
                                                <li>
                                                    <xsl:value-of select="."/>
                                                </li>
                                        </xsl:for-each>
                                    </ul>
                                </li>
                            </xsl:for-each>
                        </ul>
                    </li>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
    </xsl:stylesheet>

Output:

<html>
    <body>
        <li>Level 1 - Item 1
            <ul>
                <li>Level 2 - Item 1-1
                    <ul></ul>
                </li>
                <li>Level 2 - Item 1-2
                    <ul></ul>
                </li>
            </ul>
        </li>
        <li>Level 2 - Item 2
            <ul>
                <li>Level 2 - Item 2-1
                    <ul>
                        <li>Level 3 - Item 2-1-1</li>
                        <li>Level 3 - Item 2-1-2</li>
                        <li>Level 3 - Item 2-1-3</li>
                    </ul>
                </li>
                <li>Level 2 - Item 2-2
                    <ul>
                        <li>Level 3 - Item 2-2-1</li>
                        <li>Level 3 - Item 2-2-2</li>
                    </ul>
                </li>
            </ul>
        </li>
    </body>
</html>
神经暖 2025-01-08 11:40:16

这种简单(没有内联 XML、没有 document()contains() 函数)、简短而高效的转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:strip-space elements="*"/>

 <xsl:key name="kFollowing" match="two"
  use="generate-id(preceding-sibling::one[1])"/>

 <xsl:key name="kFollowing" match="three"
  use="generate-id(preceding-sibling::two[1])"/>

 <xsl:template match="/*">
  <ul>
    <xsl:apply-templates select="item/one" mode="inGroup"/>
  </ul>
 </xsl:template>

 <xsl:template match="one|two" mode="inGroup">
  <li><xsl:value-of select="concat(., '
')"/>
    <xsl:variable name="vGroup" select=
        "key('kFollowing', generate-id())"/>
    <xsl:apply-templates select=
       "$vGroup[1]">
     <xsl:with-param name="pGroup" select="$vGroup"/>
    </xsl:apply-templates>
  </li>
 </xsl:template>

 <xsl:template match="two|three">
  <xsl:param name="pGroup"/>

  <xsl:if test="position() = 1">
     <ul>
      <xsl:apply-templates select="$pGroup" mode="inGroup"/>
     </ul>
  </xsl:if>
 </xsl:template>

 <xsl:template match="three" mode="inGroup">
  <li><xsl:value-of select="."/></li>
 </xsl:template>
</xsl:stylesheet>

当应用于提供的 XML 文档

<doc>
    <item>
        <one>Level 1 - Item 1</one>
        <two>Level 2 - Item 1-1</two>
        <two>Level 2 - Item 1-2</two>
    </item>
    <item>
        <one>Level 2 - Item 2</one>
        <two>Level 2 - Item 2-1</two>
        <three>Level 3 - Item 2-1-1</three>
        <three>Level 3 - Item 2-1-2</three>
        <three>Level 3 - Item 2-1-3</three>
        <two>Level 2 - Item 2-2</two>
        <three>Level 3 - Item 2-2-1</three>
        <three>Level 3 - Item 2-2-2</three>
    </item>
</doc>

产生所需的正确结果

<ul>
    <li>Level 1 - Item 1
        <ul>
            <li>Level 2 - Item 1-1
            </li>
            <li>Level 2 - Item 1-2
            </li>
        </ul>
    </li>
    <li>Level 2 - Item 2
        <ul>
            <li>Level 2 - Item 2-1
                <ul>
                    <li>Level 3 - Item 2-1-1</li>
                    <li>Level 3 - Item 2-1-2</li>
                    <li>Level 3 - Item 2-1-3</li>
                </ul>
            </li>
            <li>Level 2 - Item 2-2
                <ul>
                    <li>Level 3 - Item 2-2-1</li>
                    <li>Level 3 - Item 2-2-2</li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

浏览器显示为

  • 级别 1 - 项目 1
    • 2 级 - 项目 1-1
    • 2 级 - 项目 1-2
  • 2 级 - 第 2 项
    • 2 级 - 项目 2-1
      • 3 级 - 项目 2-1-1
      • 3 级 - 项目 2-1-2
      • 3 级 - 项目 2-1-3
    • 2 级 - 项目 2-2
      • 3 级 - 项目 2-2-1
      • 3 级 - 项目 2-2-2

解释

  1. 有一个键 kFollowing(具有两个单独的定义)通过其逻辑父元素的 generate-id() 值(分别为 one两个)。这有助于我们拥有一个同时匹配 onetwo 元素的模板。

  2. 每个组中第一(twotwo)元素均在无模式下进行匹配和处理。在此模板中,生成了包装 ul,然后组中的所有元素(作为参数传递)都以名为 inGroup 的模式进行处理。

This simple (no inline XML, no document() and contains() functions), short and efficient transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:strip-space elements="*"/>

 <xsl:key name="kFollowing" match="two"
  use="generate-id(preceding-sibling::one[1])"/>

 <xsl:key name="kFollowing" match="three"
  use="generate-id(preceding-sibling::two[1])"/>

 <xsl:template match="/*">
  <ul>
    <xsl:apply-templates select="item/one" mode="inGroup"/>
  </ul>
 </xsl:template>

 <xsl:template match="one|two" mode="inGroup">
  <li><xsl:value-of select="concat(., '
')"/>
    <xsl:variable name="vGroup" select=
        "key('kFollowing', generate-id())"/>
    <xsl:apply-templates select=
       "$vGroup[1]">
     <xsl:with-param name="pGroup" select="$vGroup"/>
    </xsl:apply-templates>
  </li>
 </xsl:template>

 <xsl:template match="two|three">
  <xsl:param name="pGroup"/>

  <xsl:if test="position() = 1">
     <ul>
      <xsl:apply-templates select="$pGroup" mode="inGroup"/>
     </ul>
  </xsl:if>
 </xsl:template>

 <xsl:template match="three" mode="inGroup">
  <li><xsl:value-of select="."/></li>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<doc>
    <item>
        <one>Level 1 - Item 1</one>
        <two>Level 2 - Item 1-1</two>
        <two>Level 2 - Item 1-2</two>
    </item>
    <item>
        <one>Level 2 - Item 2</one>
        <two>Level 2 - Item 2-1</two>
        <three>Level 3 - Item 2-1-1</three>
        <three>Level 3 - Item 2-1-2</three>
        <three>Level 3 - Item 2-1-3</three>
        <two>Level 2 - Item 2-2</two>
        <three>Level 3 - Item 2-2-1</three>
        <three>Level 3 - Item 2-2-2</three>
    </item>
</doc>

produces the wanted, correct result:

<ul>
    <li>Level 1 - Item 1
        <ul>
            <li>Level 2 - Item 1-1
            </li>
            <li>Level 2 - Item 1-2
            </li>
        </ul>
    </li>
    <li>Level 2 - Item 2
        <ul>
            <li>Level 2 - Item 2-1
                <ul>
                    <li>Level 3 - Item 2-1-1</li>
                    <li>Level 3 - Item 2-1-2</li>
                    <li>Level 3 - Item 2-1-3</li>
                </ul>
            </li>
            <li>Level 2 - Item 2-2
                <ul>
                    <li>Level 3 - Item 2-2-1</li>
                    <li>Level 3 - Item 2-2-2</li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

and it is displayed by the browser as:

  • Level 1 - Item 1
    • Level 2 - Item 1-1
    • Level 2 - Item 1-2
  • Level 2 - Item 2
    • Level 2 - Item 2-1
      • Level 3 - Item 2-1-1
      • Level 3 - Item 2-1-2
      • Level 3 - Item 2-1-3
    • Level 2 - Item 2-2
      • Level 3 - Item 2-2-1
      • Level 3 - Item 2-2-2

Explanation:

  1. There is a single key kFollowing (with two separate definitions) that indexes any two or three element by the value of generate-id() of its logical parent (respectively one or two). This helps us to have a single template matching both one and two elements.

  2. Every first-in-group (two or three) element is matched and processed in no mode. In this template the wrapping ul is generated, then all elements in the group (passed as a parameter) are processed in mode named inGroup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文