如何在HTML中制作多级列表?

时间:2013-10-14 07:22:45

标签: html xml xslt html-lists

我正在解析XML文档并使用它创建HTML列表。我遇到过需要从XML数据中创建多级列表的情况。例如:

1. One
2. Two
  2.1. Three
  2.2. Four
    2.2.1. Five
    2.2.2. Six
  2.3. Seven
3. Eight

是否可以使用<ul>-<li>s在HTML中创建这样的结构?我遇到了一些建议在CSS中使用counter-incretemnt, counter-reset的解决方案,但问题是由于XML的结构,这种解决方案对我的情况不可行,并且因为使用它来编写它是非常困难的XSLT。

有人能建议我解决这个问题吗?

注意:列表的级别没有限制!

Thnx提前!!

编辑:为上述HTML列表添加示例XML:

<ele lvl="0">
  One
</ele>
<ele lvl="0">
  Two
</ele>
<ele lvl="1">
  Three
</ele>
<ele lvl="1">
  Four
</ele>
<ele lvl="2">
  Five
</ele>
<ele lvl="2">
  Six
</ele>
<ele lvl="1">
  Seven
</ele>
<ele lvl="0">
  Eight
<ele>

2 个答案:

答案 0 :(得分:4)

此XSLT样式表将您的列表输出为正确嵌套的HTML:

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

  <!-- this key indexes <ele> by their level -->
  <xsl:key name="kLevel" match="ele" use="@lvl" />

  <xsl:template match="/">
    <html>
      <head>
        <title>Nested List</title>
      </head>
      <body>
        <xsl:call-template name="list">
          <xsl:with-param name="elems" select="key('kLevel', '0')" />
        </xsl:call-template>
      </body>
    </html>
  </xsl:template>

  <!-- this makes a new list from a set of <ele> -->
  <xsl:template name="list">
    <xsl:param name="elems" />

    <ol>
      <xsl:apply-templates select="$elems" />
    </ol>
  </xsl:template>

  <!-- this makes a list item and, optionally, a sub-list -->
  <xsl:template match="ele">
    <xsl:variable name="myLevel" select="@lvl" />
    <xsl:variable name="myChildren" select="key('kLevel', $myLevel + 1)[
      generate-id(preceding-sibling::ele[@lvl = $myLevel][1])
      =
      generate-id(current())
    ]" />

    <li>
      <span><xsl:value-of select="." /></span>
      <xsl:if test="$myChildren">
        <xsl:call-template name="list">
          <xsl:with-param name="elems" select="$myChildren" />
        </xsl:call-template>
      </xsl:if>
    </li>
  </xsl:template>
</xsl:stylesheet>

的含义
key('kLevel', $myLevel + 1)[
  generate-id(preceding-sibling::ele[@lvl = $myLevel][1])
  =
  generate-id(current())
]

“所有<ele>级别为一级”key('kLevel', $myLevel + 1),即当前节点的所有潜在子级)“具有当前级别(<ele>)”的前一个generate-id(preceding-sibling::ele[@lvl = $myLevel][1])的ID,即每个潜在子级的逻辑父级“等于当前的ID节点“= generate-id(current()))。

本质上,它将节点的所有潜在子节点与其所有潜在父节点进行匹配,返回“内部连接”(如果愿意) - 实际上是当前节点的子节点的节点集

应用于您的输入:

<elems>
  <ele lvl="0">One</ele>
  <ele lvl="0">Two</ele>
  <ele lvl="1">Three</ele>
  <ele lvl="1">Four</ele>
  <ele lvl="2">Five</ele>
  <ele lvl="2">Six</ele>
  <ele lvl="1">Seven</ele>
  <ele lvl="0">Eight</ele>
</elems>

返回

<ol>
  <li><span>One</span></li>
  <li>
    <span>Two</span>
    <ol>
      <li><span>Three</span></li>
      <li>
        <span>Four</span>
        <ol>
          <li><span>Five</span></li>
          <li><span>Six</span></li>
        </ol>
      </li>
      <li><span>Seven</span></li>
    </ol>
  </li>
  <li><span>Eight</span></li>
</ol>

现在,当您申请CSS outline numbering时,

ol {
  counter-reset: section;
  list-style-type: none;
}
li:before {
  counter-increment: section;
  content: counters(section, ".") ". ";
}

你得到想要的结果

1. One
2. Two
   2.1. Three
   2.2. Four
        2.2.1. Five
        2.2.2. Six
   2.3. Seven
3. Eight

答案 1 :(得分:0)

您可以使用嵌套的<ul>标记并将它们附加到不同的类(根据级别)

例如

<ul class="treeLevel1">
 <li>root</li>
 <ul class="treeLevel2">
  <li>home</li>
 </ul>
</ul>

之后将不同的边距附加到css中的不同类(treeLevel1,treeLevel2,...)

.treeLevel1 {
    margin-left: 0.10em;
}
.treeLevel2 {
    margin-left: 0.40em;
}