2014-02-18 62 views
2

我正在遍历包含Gnomes(/ GnomeArmy/Gnome)的XML节点列表,当我迭代时,我想遍历属于gnome的子项列表。迭代XML节点

目前我已经为这两个侏儒挑选了第一个Gnome的孩子,这是不正确的,因为他们都有自己的孩子。

即Gnome1孩子是杰西卡&尼克,侏儒2孩子们也是杰西卡&尼克(这是错误的)。

谢谢。

代码:

public static List<Gnome> ReadGnomes(string file) 
{ 
    List<Gnome> gnomeList = new List<Gnome>(); 

    XmlDocument gnomeFile = new XmlDocument(); 
    gnomeFile.Load(file); 

    // Get list of Gnomes 
    XmlNodeList nodes = gnomeFile.SelectNodes(string.Format("/GnomeArmy/Gnome")); 

    Gnome gnome = null; 
    foreach (XmlNode node in nodes) 
    { 
     gnome = new Gnome(); 

     // General Attributes 
     gnome.Name = node["Name"].InnerText; 
     gnome.Colour = node["Colour"].InnerText; 

     XmlNodeList children = node.SelectSingleNode("/GnomeArmy/Gnome/Children").ChildNodes; 
     foreach (XmlNode child in children) 
     { 
      if (child.Name == "Child") 
      { 
       gnome.Children = gnome.Children + " " + child.InnerText; 
      } 
     } 
     gnomeList.Add(gnome); 
    } 
    return gnomeList; 
} 

XML:

<GnomeArmy> 

    <Gnome> 
     <Name>Harry</Name> 
     <Colour>Blue</Colour> 
     <Children> 
      <Child>Jessica</Child> 
      <Child>Nick</Child> 
     </Children> 
    </Gnome> 

    <Gnome> 
     <Name>Mathew</Name> 
     <Colour>Red</Colour> 
     <Children> 
      <Child>Lisa</Child> 
      <Child>James</Child> 
     </Children> 
    </Gnome> 

</GnomeArmy> 

回答

2

尝试使用LINQ to XML

List<Gnome> gnomes = XDocument.Load("path") 
        .Descendants("Gnome") 
        .Select(g => new Gnome { 
         Name = (string)g.Element("Name"), 
         Colour = (string)g.Element("Colour"), 
         Childrens = g.Element("Children") 
          .Elements("Child") 
          .Select(x => new Children { Name = (string)x)).ToList()); 

我存储ChildrensList,你可以改变它,如果你想正好连接的孩子名字,你可以使用string.Join在:

Childrens = string.Join(" ",g.Element("Children") 
      .Elements("Child") 
      .Select(x => (string)x)); 
1

使用LINQ来处理节点和子(分)通过其Descendants

var xdoc = XDocument.Parse(@" 
    <GnomeArmy> 
     <Gnome><Name>Harry</Name><Colour>Blue</Colour> 
      <Children><Child>Jessica</Child><Child>Nick</Child></Children> 
     </Gnome> 
     <Gnome><Name>Mathew</Name><Colour>Red</Colour> 
      <Children><Child>Lisa</Child><Child>James</Child></Children> 
     </Gnome> 
    </GnomeArmy>"); 


Console.WriteLine (
xdoc.Descendants("Gnome") 
    .Select (parent => string.Format("{0} has these kids {1}", 
            parent.Descendants("Name").First().Value, 
            string.Join(", ", parent.Descendants("Child") 
                  .Select (child => child.Value)) 
            ) 
      )); 

结果从的WriteLine相应节点

Harry has these kids Jessica, Nick 
Mathew has these kids Lisa, James 
1

你的问题是这样的一行:

XmlNodeList children = node.SelectSingleNode("/GnomeArmy/Gnome/Children").ChildNodes; 

您一遍又一遍地选择相同的节点。

SelectSingleNode

0

事实证明,这是问题,因为通过@JonPall说:

XmlNodeList children = node.SelectSingleNode("/GnomeArmy/Gnome/Children").ChildNodes; 

这是造成问题的原因是该声明的一部分 “/ GnomeArmy /” 时,/导致在去的SelectSingleNode对XML文档的顶部,去掉“/ GnomeArmy”和“/”和它的工作原理:)

XmlNodeList children = node.SelectSingleNode("Gnome/Children").ChildNodes; 

感谢我的讲师和@JonPall为HIG强调代码行。