迭代XML节点

时间:2014-02-18 18:43:46

标签: c# xml

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

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

即。 Gnome1儿童是Jessica& Nick,Gnome2孩子们也是Jessica&尼克(这是错的)。

感谢。

代码:

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>

4 个答案:

答案 0 :(得分: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());

我将Childrens存储到List中,您可以更改它,如果您只想连接子名称,可以使用string.Join

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

答案 1 :(得分: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

答案 2 :(得分:1)

你的问题就在这一行:

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

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

SelectSingleNode

答案 3 :(得分:0)

事实证明,这是@JonPall所说的问题:

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

导致问题的那个语句的部分是“/ GnomeArmy /”,/导致SelectSingleNode到达XML Doc的顶部,删除“/ GnomeArmy”和“/”并且它有效:)

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

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