Reputation: 934
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.
Upvotes: 1
Views: 3272
Reputation: 34421
try ReadFrom() method in xml linq
while (reader.Read())
{
if (reader.Name.Equals("Group"))
{
XElement group = (XElement)XDocument.ReadFrom(reader);
}
}
reader.Close();
Upvotes: 1
Reputation: 11228
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}");
Upvotes: 2
Reputation: 26213
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.
Upvotes: 1