2014-01-13 52 views
2

我试图读取嵌套XML用的XMLNode但我有一个问题阅读与XmlNode的嵌套的XML

这里是我的xml文件

<role name="admin"> 
<menu name="Setting"> 
    <group name="settinggrup1"></group> 
    <group name="settinggrup2"></group> 
    <group name="settinggrup3"></group> 
</menu> 
<menu name="Service"> 
    <group name="servicegrup1"></group> 
    <group name="servicegrup2"></group> 
    <group name="servicegrup3"></group> 
</menu> 
<menu name="Search"> 
    <group name="serchgrup1"></group> 
    <group name="serchgrup2"></group> 
    <group name="serchgrup3"></group> 
</menu> 
</role> 

,这里是我的代码

var xmlDoc = new XmlDocument(); 
xmlDoc.Load(file); 
XmlNodeList nodeList = xmlDoc.SelectNodes("//role[@name='" + "admin" + "']/menu"); 
var menus = new List<Menu>(); 
var groupName = new List<Group>(); 
Menu menu = new Menu(); 

foreach (XmlNode menuNode in nodeList) 
      {     
       menu.name = menuNode.Attributes["name"].Value; 

       foreach (XmlNode childNode in menuNode) 
       { 
        groupName.Add(new Group() { name = childNode.Attributes["name"].Value }); 
       } 
       menus.Add(new Menu { name = menu.name, group = groupName }); 
      } 

这里是我的班级

public class Menu 
{ 
    public string name { get; set; } 
    public List<Group> group { get; set; } 
} 
public class Group 
{ 
    public string name { set; get; } 
} 

而通过,我打算显示像

  • 设置:settinggrup1,settinggrup2,settinggrup3
  • 服务:servicegrup1,servicegrup2,servicegrup3
  • 搜索:searchgrup1,searchgrup2,searchgrup3

但我得到的是这个

  • Setting:settinggrup1,settinggrup2,settinggrup3,servicegrup1, servicegrup2,servicegrup3,searchgrup1,searchgrup2,searchgrup3
  • 服务:settinggrup1,settinggrup2,settinggrup3,servicegrup1, servicegrup2,servicegrup3,searchgrup1,searchgrup2,searchgrup3
  • 搜索:settinggrup1,settinggrup2,settinggrup3,servicegrup1, servicegrup2,servicegrup3 ,searchgrup1,searchgrup2,searchgrup3

有什么问题在我的代码的一部分,我想在一部分时,我在嵌套的foreach添加名单,但我一直在尝试几个小时,仍无法修复它。任何人都可以帮助我,还请解释我的代码做错了什么。

回答

1

你的问题是,您要添加的所有组群列表相同的实例。然后你将所有组的内部列表分配给所有菜单。

下面是正确的代码:

var menus = new List<Menu>(); 

foreach (XmlNode menuNode in nodeList) 
{ 
    var groupName = new List<Group>(); // create list here 

    foreach (XmlNode childNode in menuNode) 
     groupName.Add(new Group { name = childNode.Attributes["name"].Value }); 

    menus.Add(new Menu { 
     name = menuNode.Attributes["name"].Value, 
     group = groupName 
    }); 
} 

您可以使用LINQ到XML:

var xdoc = XDocument.Load(file); 
var menus = xdoc.Descendants("role") 
       .Where(r => (string)r.Attribute("name") == "admin") 
       .Elements("menu") 
       .Select(m => new Menu { 
        name = (string)m.Attribute("name"), 
        group = m.Elements("group") 
           .Select(g => new Group { 
            name = (string)g.Attribute("name") 
           }).ToList() 
       }).ToList(); 

或者使用XPath:

var menus = xdoc.XPathSelectElements("//role[@name='admin']/menu") 
       .Select(m => new Menu { /* create menu as above */ }) 
       .ToList(); 

BTW考虑用更好的命名和Pascal情况公众成员名称:

public class Menu 
{ 
    public string Name { get; set; } 
    public List<Group> Groups { get; set; } 
} 
+1

感谢您的响应。 是使用LINQ只有这样,才能做呢?因为,我不满意,我不知道我做错了什么关于我的代码 – Laxus

+1

呼我明白了,我没有得到一个新的群组列表,我应该让我的循环中的新的。它现在被清除,感谢很多人 – Laxus

1

作为一个快速的解决方案:

// after 
menu.name = menuNode.Attributes["name"].Value; 
//please add 
groupName = new List<Group>(); 
+0

是的,你说得对,非常感谢的人 – Laxus