使用XmlNode读取嵌套XML

时间:2014-01-13 10:39:33

标签: c# xml nested-attributes 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

但我得到的是这个

  • 设置: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中添加列表的部分,但我已经尝试了几个小时仍然无法解决它。任何人都可以帮助我,并且,请解释我的代码做错了什么。

2 个答案:

答案 0 :(得分: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 to 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 :(得分:1)

作为快速解决方案:

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