2014-01-13 49 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