0

我正在解析一个 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

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

谁能建议我解决这个问题?

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

提前谢谢!!

编辑:为上述所需的 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>
4

2 回答 2

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)即当前节点的所有潜在子节点)“其中前一个节点的 ID<ele> 具有当前级别 ( generate-id(preceding-sibling::ele[@lvl = $myLevel][1]))”,即每个潜在子节点的逻辑父节点)“等于 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 大纲编号时,

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

你得到想要的结果

1. 一个
2. 两个
   2.1。三
   2.2. 四
        2.2.1。五
        2.2.2。六
   2.3. 七
3. 八
于 2013-10-14T10:54:27.170 回答
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;
}
于 2013-10-14T07:39:27.330 回答