2011-11-23 51 views
0

我在尋找一種算法,將轉換爲數據結構類似以下,其中每一級都用點分隔的文本層次HTML列表:構建基於與點

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

你能告訴我們你到目前爲止嘗試和在那裏你卡住了? – ChrisWue

+0

數據開始或多或少像您的示例所示?更具體地說,你是從以'.'分隔結構的字符串開始的嗎? –

+0

解析爲一些樹型數據結構,然後編寫一個合適的「轉儲」方法來獲取HTML。 – John3136

回答

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>"); 
     } 
    } 
+0

謝謝,正是我在尋找的 – wicherqm

+0

有沒有什麼辦法可以在writelevel中找到當前的完整節點路徑? – wicherqm

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); 
       } 
      } 
     } 
    } 
} 
+0

謝謝你也很有趣,它的工作 – wicherqm