我尝试用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; }
}
由此,我打算显示像
但我得到的是这个
我的代码部分出了问题,我想在我嵌套的foreach中添加列表的部分,但我已经尝试了几个小时仍然无法解决它。任何人都可以帮助我,并且,请解释我的代码做错了什么。
答案 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>();