Reputation: 177
I am looking to loop thru an element based off one attribute, "sequence" , to retrieve another, "strokes".
My xml is as follows:
<tournament>
<leaderboard>
<player first_name="Jimmy" last_name="Walker" country="UNITED STATES" id="2db60f6e-7b0a-4daf-97d9-01a057f44f1d" position="1" money="900000.0" points="500.0" score="-17" strokes="267">
<rounds>
<round score="-1" strokes="70" thru="18" eagles="0" birdies="5" pars="9" bogeys="4" double_bogeys="0" other_scores="0" sequence="1"/>
<round score="-2" strokes="69" thru="18" eagles="0" birdies="3" pars="14" bogeys="1" double_bogeys="0" other_scores="0" sequence="2"/>
<round score="-9" strokes="62" thru="18" eagles="0" birdies="10" pars="7" bogeys="1" double_bogeys="0" other_scores="0" sequence="3"/>
<round score="-5" strokes="66" thru="18" eagles="0" birdies="6" pars="11" bogeys="1" double_bogeys="0" other_scores="0" sequence="4"/>
</rounds>
</player>
</leaderboard>
</tournament>
I am able to retrieve individual round elements based on the following code:
// EDITED TO REFLECT SOLUTION
foreach (XmlNode player in doc.GetElementsByTagName("player"))
{
string strokes;
dtAttributeList.Rows.Add(
player.Attributes["last_name"].Value,
player.Attributes["first_name"].Value,
player.Attributes["position"].Value,
player.Attributes["score"].Value);
if (player.HasChildNodes)
{
foreach (XmlNode round in player.LastChild)
{
strokes = round.Attributes["strokes"].Value;
dtAttributeList.Rows.Add(strokes);
}
}
}
however in doing this I am only able to retrieve the first element and its values.
please help me find a solution to loop thru the "round" elements either via a filter on sequence or a loop of some sort.
Upvotes: 0
Views: 24
Reputation: 101690
It's much easier to use XPath for this than the approach you've tried above. You're also creating a huge amount of duplicate code by using a for
loop instead of foreach
:
foreach (XmlNode player in doc.GetElementsByTagName("player"))
{
string strokes;
dtAttributeList.Rows.Add(
player.Attributes["last_name"].Value,
player.Attributes["first_name"].Value,
player.Attributes["position"].Value,
player.Attributes["score"].Value);
foreach (XmlNode round in player.SelectNodes("rounds/round"))
{
strokes = round.Attributes["strokes"].Value;
dtAttributeList.Rows.Add(strokes);
}
}
If you need to iterate throug them based on the order of sequence
(and they're not already in order), you can do this:
var rounds = player.SelectNodes("rounds/round")
.OfType<XmlNode>()
.OrderBy(n => int.Parse(n.Attributes["sequence"].Value));
foreach (XmlNode round in rounds)
{
// ...
}
Upvotes: 1