简体   繁体   中英

Reading Sub-Elements (child nodes) with XMLreader using C#

First: This is NOT a duplicate of Reading Child Nodes with XMLReader (Not the same language, Couldn't get it to help me).

I'm pretty new to XMLreading, I am trying to reach the Sub Element of a specific Element but I am having hard time reaching it, here is an example:

The XML element:

<Group ExerciseNumber="0" Name="R33-IOS1_IOS1" ExerciseName="Unallocated" Status="offline" StatusStatistics="0/1">
      <Clients>
        <Client ClientName="R33-IOS1_IOS1" MachineName="R33-IOS1" ClientType="HC0" ClientStatus="Disconnected" />
      </Clients>
      <GroupAppendedData GroupID="201" Type="IOS" DomeType="None" ConnectedTo="" ForceType="Enemy" />
    </Group>

I am trying to reach the "Client" element from the specific "Group" element, This is my C# code:

while (reader.Read())
            {
                if (reader.Name.Equals("Group"))
                {
                    name = reader.GetAttribute("Name");
                    // Now I need to reach the specific "MachineName" attribute of the "Client" sub-element but don't know how.
                }
            }
            reader.Close();

Notes: It's important that the client element reading will be in the same loop iteration (if possible, if not I will have to think of another design for my generating class).

*Editing the XML is not an option.

Thank you.

LINQ to XML would be easier to use than XmlReader, this will give you machine names for all Clients in the document:

var machineNames = XElement.Parse("data.xml")
                           .Descendants("Client")
                           .Select(client => client.Attribute("MachineName").Value);

Edit - this returns both names in every iteration:

var query = XElement.Load("data.xml")
                    .Descendants("Client")
                    .Select(client => new {
                               MachineName = client.Attribute("MachineName").Value,
                               GroupName = client.Ancestors("Group").Select(g => g.Attribute("Name").Value).First()
                           });

foreach (var x in query)
    Console.WriteLine($"GroupName: {x.GroupName}, MachineName: {x.MachineName}");

As suggested, unless you have a very good reason to use XmlReader then using a higher level API such as LINQ to XML would be preferred.

Here's a solution using query syntax:

var clients = from @group in doc.Descendants("Group")
              let groupName = (string) @group.Attribute("Name")
              from client in @group.Descendants("Client")
              select new
              {
                  GroupName = groupName,
                  ClientName = (string) client.Attribute("ClientName"),
                  MachineName = (string) client.Attribute("MachineName"),
              };

See this fiddle for a working example.

try ReadFrom() method in xml linq

            while (reader.Read())
            {
                if (reader.Name.Equals("Group"))
                {
                    XElement group =  (XElement)XDocument.ReadFrom(reader);
                }
            }
            reader.Close();​

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM