Reputation: 77
I am attempting to get the value of a specific node for each parent element found. In the example I want to return each students First Name. Instead I am getting the first elements name in each instance. The InnerText of a Student is correct but the InnerText of FirstName is always Alex.
var xml = @"<School>
<Students>
<Student>
<FirstName>Alex</FirstName>
<LastName>Smith</LastName>
<Grade>11</Grade>
</Student>
<Student>
<FirstName>Joanne</FirstName>
<LastName>Robins</LastName>
<Grade>12</Grade>
</Student>
<Student>
<FirstName>Steve</FirstName>
<LastName>Baker</LastName>
<Grade>11</Grade>
</Student>
</Students>
<Teachers>
<Teacher>
<FirstName>George</FirstName>
<LastName>Roberts</LastName>
<Grade>11</Grade>
</Teacher>
<Teacher>
<FirstName>Amanda</FirstName>
<LastName>Walker</LastName>
<Grade>12</Grade>
</Teacher>
<Teacher>
<FirstName>Tracey</FirstName>
<LastName>Smith</LastName>
<Grade>12</Grade>
</Teacher>
</Teachers>
</School>";
var doc = new XmlDocument();
doc.LoadXml(xml);
var resourceTypeNodes = doc.GetElementsByTagName("Student");
var resourceTypesIterator = resourceTypeNodes.GetEnumerator();
while (resourceTypesIterator != null && resourceTypesIterator.MoveNext())
{
var resourceTypeNode = resourceTypesIterator.Current as XmlNode;
var typeNameElement = resourceTypeNode.SelectSingleNode("//FirstName");
Console.WriteLine(resourceTypeNode.InnerXml);
Console.WriteLine(typeNameElement.InnerText);
}
This is the output of the above code.
<FirstName>Alex</FirstName><LastName>Smith</LastName><Grade>11</Grade>
Alex
<FirstName>Joanne</FirstName><LastName>Robins</LastName><Grade>12</Grade>
Alex
<FirstName>Steve</FirstName><LastName>Baker</LastName><Grade>11</Grade>
Alex
What am I missing?
Upvotes: 1
Views: 675
Reputation: 67090
Because you're using //FirstName
XPath expression, that will always return first node from root, it doesn't matter if you invoke on children. Just change this:
var typeNameElement = resourceTypeNode.SelectSingleNode("//FirstName");
To this:
var typeNameElement = resourceTypeNode.SelectSingleNode("FirstName");
Moreover is there any specific reason you're manually using IEnumerator
? You may simplify your code with foreach
:
foreach (XmlNode resourceTypeNode in doc.GetElementsByTagName("Student"))
{
var typeNameElement = resourceTypeNode.SelectSingleNode("FirstName");
Console.WriteLine(resourceTypeNode.InnerXml);
Console.WriteLine(typeNameElement.InnerText);
}
Upvotes: 1