我正在寻找一种算法,该算法将转换如下所示的数据结构,其中每个级别用点分隔:
child1
child1.child9
child4.child10.child11
child4.child10.child12
进入一个有效的HTML分层列表元素,如下所示:
<ul>
<li>child1
<ul><li>child9</li></ul></li>
<li>child4
<ul><li>child10
<ul><li>child11</li><li>child12</li></ul></li></ul></li>
</ul>
有什么建议吗?
更新
问题 从这种结构(下面)很容易建立分层列表
child
child.child1
child.child2
child.child2.child3
但我的结构是
child.child2.child3
child7
child10.child14.child15
child10.child14.child16
所以我没有单独的行来构建父元素:(如果没有父元素,我必须从一行构建树
答案 0 :(得分:1)
您可以将列表转换为矩阵,然后使用分组/递归。这是一个例子。它不会打印HTML,但它应该给出正确的结果。
static void Main(string[] args)
{
var list = new List<String>()
{
"child.child2.child3",
"child7",
"child10.child14.child15",
"child10.child14.child16"
};
var matrix = new List<List<String>>();
foreach (var line in list)
{
matrix.Add(line.Split('.').ToList());
}
StringBuilder html = new StringBuilder();
WriteLevel(html, matrix, 0);
Console.WriteLine(html.ToString());
}
static void WriteLevel(StringBuilder html, List<List<String>> matrix, int level)
{
var nodes = from node in matrix
where node.Count > level
group node by node[level] into grouping
select grouping;
if (nodes.Count() > 0)
{
html.Append("<ul>");
foreach (var node in nodes)
{
html.Append("<li>");
html.Append(node.Key);
WriteLevel(html, node.ToList(), level + 1);
html.Append("</li>");
}
html.Append("</ul>");
}
}
答案 1 :(得分:1)
using System;
using System.Xml;
using System.Collections.Generic;
class Sample{
static void Main(string[] args){
var doc = new XmlDocument();
doc.LoadXml(@"
<!DOCTYPE root [
<!ELEMENT root (ul*) >
<!ELEMENT ul (li+) >
<!ELEMENT li ANY >
<!ATTLIST root id ID #REQUIRED>
<!ATTLIST li id ID #REQUIRED>]>
<root id='root'></root>");
var relation = new List<String>(){
"child.child2.child3",
"child7",
"child10.child14.child15",
"child10.child14.child16"
};
/* output(by hand made pretty):
<ul>
<li>child<ul><li>child2<ul><li>child3</li></ul></li></ul></li>
<li>child7</li>
<li>child10<ul><li>child14<ul><li>child15</li><li>child16</li></ul></li></ul></li>
</ul>
*/
/*
var relation = new List<String>(){
"child1",
"child1.child9",
"child4.child10.child11",
"child4.child10.child12"
};
var relation = new List<String>(){
"child",
"child.child1",
"child.child2",
"child.child2.child3"
};
*/
foreach(var path in relation){
MakeTree(doc, path);
}
DeleteId(doc.DocumentElement);
string result = doc.DocumentElement.InnerXml;
Console.WriteLine(result);
// doc.Save(Console.Out);
}
static void MakeTree(XmlDocument doc, string path){
string parent = "root";
foreach(var node in path.Split('.')){
AppendChild(doc, parent, node);
parent = node;
}
}
static void DeleteId(XmlElement el){
el.RemoveAttribute("id");
if(el.HasChildNodes){
foreach(XmlNode node in el.ChildNodes){
if(node.NodeType == XmlNodeType.Element){
DeleteId((XmlElement)node);
}
}
}
}
static void AppendChild(XmlDocument doc, string parent, string child){
var childElement = doc.GetElementById(child);
if(childElement == null){
var li = doc.CreateElement("li");
var text = doc.CreateTextNode(child);
li.SetAttribute("id", child);
li.AppendChild(text);
var parentElement = doc.GetElementById(parent);
if(parent == "root"){
if(parentElement.HasChildNodes){
parentElement.FirstChild.AppendChild(li);
} else {
var ul = doc.CreateElement("ul");
ul.AppendChild(li);
parentElement.AppendChild(ul);
}
} else {
if(parentElement.LastChild.NodeType == XmlNodeType.Text){
var ul = doc.CreateElement("ul");
ul.AppendChild(li);
parentElement.AppendChild(ul);
} else {
parentElement.LastChild.AppendChild(li);
}
}
}
}
}