我正在解析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>
答案 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;
}