English 中文(简体)
根据带有斜体的案文建立一个等级的超文本清单
原标题:Building a hierarchical HTML list based on text with dots
  • 时间:2011-11-23 23:40:27
  •  标签:
  • c#
  • html
  • tree

I m 寻找一种算法,将转换如下一种数据结构,即每个等级由直线分开:

child1
child1.child9
child4.child10.child11
child4.child10.child12

a) 列入有效的超等级名单,如:

<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>

任何建议?

A. 更新

Problem from this kind of structure(below) is easy to build hierarchical list

child
child.child1
child.child2
child.child2.child3

但我的结构是:

child.child2.child3
child7
child10.child14.child15
child10.child14.child16

i) 独有一行,以建设母体元素: i) 如果没有父母,就必须从一行 build树。

最佳回答

你可以把清单变成一个矩阵,然后使用分类/再交易。 这里就是一个例子。 它只是粗略地印刷了超文本,但应当给出正确的结果。

    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>");
        }
    }
问题回答
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);
                }
            }
        }
    }
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签