2010-05-24 73 views
1

我对xml非常陌生,所以我希望我不会在这里问任何愚蠢的问题。我目前正在从未分层结构的XML文件中填充树视图。在我给出的xml文件中,子项和父项节点在item元素的属性中定义。我将如何能够利用这些属性以便树视图以正确的层级顺序填充。 (例如Mary Jane应该是Peter Smith的孩子节点)。目前所有名字都在彼此之下。格式化由XML文件填充的Treeview的父节点和子节点

<item parent_id="0" id="1"><content><name>Peter Smith</name></content></item> 
<item parent_id="1" id="2"><content><name>Mary Jane</name></content></item> 
<item parent_id="1" id="7"><content><name>Lucy Lu</name></content></item> 
<item parent_id="2" id="3"><content><name>Informatics Team</name></content></item> 
<item parent_id="3" id="4"><content><name>Sandy Chu</name></content></item> 
<item parent_id="4" id="5"><content><name>John Smith</name></content></item> 
<item parent_id="5" id="6"><content><name>Jane Smith</name></content></item> 

/根

感谢您所有的帮助, 滨海

回答

2

下面是使用LINQ to XML的解决方案:

string strXML = @"<root> 
     <item parent_id='0' id='1'><content><name>Peter Smith</name></content></item> 
     <item parent_id='1' id='2'><content><name>Mary Jane</name></content></item> 
     <item parent_id='1' id='7'><content><name>Lucy Lu</name></content></item> 
     <item parent_id='2' id='3'><content><name>Informatics Team</name></content></item> 
     <item parent_id='3' id='4'><content><name>Sandy Chu</name></content></item> 
     <item parent_id='4' id='5'><content><name>John Smith</name></content></item> 
     <item parent_id='5' id='6'><content><name>Jane Smith</name></content></item> 
     </root>"; 

    XDocument xDoc = XDocument.Parse(strXML, LoadOptions.None); 

    var objData = xDoc.Root.Elements("item").ToList().Select(item => 
     new { id = item.Attribute("id").Value, 
       pid = item.Attribute("parent_id").Value, 
       tn = new TreeNode(item.Element("content").Element("name").Value) 
     }).ToList(); 

    objData.ForEach(child => 
     { 
      var parent = objData.FirstOrDefault(m => m.id == child.pid); 
      if (parent != null) 
       parent.tn.Nodes.Add(child.tn); 
     }); 
    // Add all nodes with no parent to the TreeView's root: 
    objData.Where(n => n.tn.Parent == null).ToList().ForEach(n => treeView1.Nodes.Add(n.tn)); 
+0

嗨西蒙, 谢谢你的代码。我试图添加这个,虽然它没有正确地拾取parent.tn.Nodes.Add(child.tn)。你会有一个想法,为什么(特别是“节点”)? 错误指出它是一种在给定上下文中无效的方法。 非常感谢! Marina – Maria 2010-05-24 20:14:33

+0

嗨Marina,这可能是你的项目缺少对System.Windows.Forms.dll的引用或使用语句。如果它帮助我的VS 2010解决方案暂时在http://www.simonchadwick.com/Transfer/WindowsFormsApplication2.zip。最好的祝愿! – 2010-05-24 20:56:42

+0

嗨西蒙, 你是对的,这是参考。感谢您的解决方案,这是相当有益的! 非常好, 玛丽娜 – Maria 2010-05-24 21:49:25

0

一个可能的算法是这样的: 1)获取parent_id节点列表作为一个独特的收藏(记得从所有藏品中删除重复)

2)获取集合

3)在id集合创建新的空“parents”收集

4)对于每个项目,如果parent_id集合中存在相应的项目中个属性,则该产品一些其他的父项目。您将此ID添加到您创建的新parents集合

5)在您有父母名单后,将其绑定到树上。这是您的顶级树元素。

6)在此之后,你可以再次通过ID收集和使用PARENT_ID属性

知不知道这是不是最有效的实现,因为你遍历集合类,每个项目只需要添加到它的父几次而不是在一次传球中完成任何事情(算法肯定会有所不同)。所以如果收藏品很小,那么以上是一个好方法。但它有成千上万的项目,多次浏览收藏可能会对性能造成影响。但是这种方法实施起来快而简单。因此请记住权衡。

此外,由于您只通过XML阅读并且没有操作它,所以更喜欢XMLReader类而不是XMLDocument

+0

嗨, 感谢您对上述建议。名单是相当小的,所以我会尝试并实施上述。 再次感谢, Marina – Maria 2010-05-24 20:09:19