C# 使用XmlNode读取嵌套XML

C# 使用XmlNode读取嵌套XML,c#,xml,nested-attributes,xmlnode,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> &l

我试图用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 });  
            }
var xmlDoc=new XmlDocument();
加载(文件);
XmlNodeList nodeList=xmlDoc.SelectNodes(//role[@name='“+”admin“+”]/menu”);
变量菜单=新列表();
var groupName=新列表();
菜单=新菜单();
foreach(节点列表中的XmlNode menuNode)
{                
menu.name=menuNode.Attributes[“name”].Value;
foreach(菜单节点中的XmlNode-childNode)
{
添加(新组(){name=childNode.Attributes[“name”].Value});
} 
添加(新菜单{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; }
}
公共类菜单
{
公共字符串名称{get;set;}
公共列表组{get;set;}
}
公共课组
{
公共字符串名称{set;get;}
}
因此,我打算像这样展示

  • 设置:设置GRUP1、设置GRUP2、设置GRUP3
  • 服务:servicegrup1、servicegrup2、servicegrup3
  • 搜索:searchgrup1、searchgrup2、searchgrup3
但我得到的是这个

  • 设置:设置GRUP1、设置GRUP2、设置GRUP3、服务GRUP1、, servicegrup2,servicegrup3,searchgrup1,searchgrup2,searchgrup3
  • 服务:设置GRUP1、设置GRUP2、设置GRUP3、服务GRUP1、, servicegrup2,servicegrup3,searchgrup1,searchgrup2,searchgrup3
  • 搜索:设置GRUP1、设置GRUP2、设置GRUP3、服务GRUP1、, servicegrup2,servicegrup3,searchgrup1,searchgrup2,searchgrup3

我的代码部分出错了,我猜是在嵌套foreach中添加列表时出错的,但我已经尝试了几个小时,仍然无法修复它。任何人都可以帮助我,并且,请解释我的代码哪里出错。

您的问题是您正在将所有组添加到组列表的同一实例中。然后,将包含所有组的列表分配给所有菜单

下面是正确的代码:

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
     });  
}
或者使用xpath:

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

考虑对公共成员名称使用更好的命名和Pascal情况:

public class Menu
{
    public string Name { get; set; }
    public List<Group> Groups { get; set; }
}
公共类菜单
{
公共字符串名称{get;set;}
公共列表组{get;set;}
}
作为快速解决方案:

// after
menu.name = menuNode.Attributes["name"].Value; 
//please add
groupName = new List<Group>();
//之后
menu.name=menuNode.Attributes[“name”].Value;
//请加上
groupName=新列表();

感谢您的回复。使用LINQ是实现这一目标的唯一方法吗?因为我还不满意,我不知道我的代码错在哪里了我明白了,我没有得到一个新的组列表,我应该在我的循环中创建一个新的组列表。现在没事了,多谢了,伙计
// after
menu.name = menuNode.Attributes["name"].Value; 
//please add
groupName = new List<Group>();