Iterate through SelectNodes in C#

时间:2015-11-12 10:54:46

标签: c# xmldocument

I've an XML with this structure:

<?xml version="1.0" encoding="UTF-8"?>
<Road Version="4.0">
  <Group Caption="Church Street">
    <Group Caption="Num3">
       <Group Caption="Floor1">
          <Group Caption="ApartmentXYZ">[...]</Group>
       </Group>
    </Group>
    <Group Caption="Num4">
       <Group Caption="Floor1">
          <Group Caption="ApartmentXYZ2">[...]</Group>
          <Group Caption="ApartmentXYZ3">[...]</Group>
       </Group>
       <Group Caption="Floor2">
          <Group Caption="ApartmentXYZA">[...]</Group>
          <Group Caption="ApartmentXYZB">[...]</Group>
       </Group>
    </Group>
    <Group Caption="Num1">
       <Group Caption="Floor1">
          <Group Caption="ApartmentXYZZ">[...]</Group>
          <Group Caption="ApartmentXYZY">[...]</Group>
       </Group>
    </Group>
    <Group Caption="Num6">
       <Group Caption="Floor1">
          <Group Caption="ApartmentXYZ0">[...]</Group>
          <Group Caption="ApartmentXYZ9">[...]</Group>
       </Group>
    </Group>
[...]

At the moment I'm using this code to get data from level where I have Caption="NumX" (it is my starting level):

XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString);
XmlNodeList xnList = xml.SelectNodes("/Road/Group/Group");

It works fine.

Now I have to get data from sub level nodes.

I mean, I'm into "Num3" node, then I have to get all sub levels "Group" (Caption = "FloorX"), then for each "FloorX" I have to extract the first sub level "Group" (Caption = "Apartment") etc...

I'm trying to use foreach like this (xnList is defined in the code before):

foreach (XmlNode xn in xnList)
   {
   string scala = xn.Attributes["Caption"].Value;

   XmlDocument xmlFloor = new XmlDocument();
   xmlFloor.LoadXml(xn.InnerXml);
   XmlNodeList xnListFloor = xmlFloor.SelectNodes("Group");
   [...]

But it doesn't work.

Which is the best way (and the correct way) to do that?

1 个答案:

答案 0 :(得分:0)

You can create POCO classes that would contain nested Group objects like this:

public class Road
{
    [XmlElement("Group")]
    public List<Group> Groups { get; set; }
}

public class Group
{
    [XmlElement("Group")]
    public List<Group> Groups { get; set; }

    [XmlAttribute]
    public string Caption { get; set; }
}

and you can deserialize to Road like this:

var ser = new XmlSerializer(typeof(Road));
using (var reader = new StreamReader("XMLFile1.xml"))
{
    var road = (Road)ser.Deserialize(reader);
    Console.WriteLine(road.Groups[0].Groups[0].Groups[0].Caption);
}

This way you can loo through all sub group elements. The sample above would print "Floor1" for instance