Reputation: 3095
I have the following XML
<root>
<Operations>
<OperationId>1</OperationId>
<OtherFields>...</OtherFields>
</Operations>
<Operations>
<OperationId>2</OperationId>
<OtherFields>...</OtherFields>
</Operations>
<Operations>
<OperationId>3</OperationId>
<OtherFields>...</OtherFields>
</Operations>
</root>
Using C# and System.XML namespace I get all operations using this code:
XmlNodeList operations= doc.SelectNodes("/root/Operations");
Now I need to loop through each operation and reference the fields (OperationId, OtherFields).
I try this:
foreach (XmlNode node in xnodes)
{
Console.WriteLine("Operation ID: {0}", node.SelectNodes("//OperationId")[0].InnerText);
}
However this just repeats the first OperationId - 1.
What is wrong?
Thanks, Andrew
Upvotes: 4
Views: 3934
Reputation: 134591
Your initial query selects all Operations
nodes off the root like you're expecting. However your inner query in your loop does something different.
By starting your query with a //
, you're querying relative to the root of the document. So you're actually selecting all OperationId
nodes in the document, not just the descendant children of the current node. You then index the first node in that result for every iteration which is why you're seeing the first id repeating.
Since node
refers to the current Operations
node, to select the corresponding OperationId
, your query should simply be:
OperationId
I should mention that since you're only trying to select the first element of the query, it would be better to use SelectSingleNode()
instead of SelectNodes
. If there are any nodes selected, the first will be returned.
node.SelectSingleNode("OperationId").InnerText
However since you're only trying to select an immediate child element, I wouldn't use an XPath query there, it's unnecessary. Just access the child element directly using the indexer.
var query = doc.SelectNodes("/root/Operations");
foreach (XmlNode node in query)
{
Console.WriteLine("Operation ID: {0}", node["OperationId"].InnerText);
}
Upvotes: 7