Question

i tried to read nested XML with xmlnode but i got one issue

here is my xml file

<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>

and here is my code

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 });  
            }

here is my class

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

And by that, i intended to display like

  • Setting : settinggrup1, settinggrup2, settinggrup3
  • Service : servicegrup1, servicegrup2, servicegrup3
  • Search : searchgrup1, searchgrup2, searchgrup3

But what i got is this

  • Setting : settinggrup1, settinggrup2, settinggrup3, servicegrup1, servicegrup2, servicegrup3, searchgrup1, searchgrup2, searchgrup3
  • Service : settinggrup1, settinggrup2, settinggrup3, servicegrup1, servicegrup2, servicegrup3, searchgrup1, searchgrup2, searchgrup3
  • Search : settinggrup1, settinggrup2, settinggrup3, servicegrup1, servicegrup2, servicegrup3, searchgrup1, searchgrup2, searchgrup3

Something wrong in my code part, i guess at the part when i added list at my nested foreach, but i've been trying for hours and still can't fix it. anyone can help me please, and also, please explain what my code did wrong.

Était-ce utile?

La solution

Your problem is that you are adding all groups to same instance of groups list. And then you are assigning that list with all groups inside to all menus.

Here is correct code:

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
     });  
}

You can use 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();

Or with xpath:

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

BTW consider to use better naming and pascal case for public member names:

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

Autres conseils

As a fast solution:

// after
menu.name = menuNode.Attributes["name"].Value; 
//please add
groupName = new List<Group>();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top