Colonel Panic
Colonel Panic

Reputation: 137594

Linq to xml for loop terminating early and unexpectedly

My linq to xml foreach loop is terminating early and unexpectedly. No exception raised. What's going on?


var doc = XDocument.Parse("<a><b>one</b><b>two</b></a>");

foreach(var element in doc.Root.Elements("b"))
{
 element.ReplaceWith(XElement.Parse("<c>fixed</c>"));
}

doc.Dump();

Gives me

<a>
  <c>fixed</c>
  <b>two</b>
</a>

When I expected

<a>
  <c>fixed</c>
  <c>fixed</c>
</a>

Upvotes: 1

Views: 175

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500675

My linq to xml foreach loop is terminating early and unexpectedly. What's going on?

It's generally a bad idea to modify the document when you're iterating over a lazily evaluated query on the same document. In some cases it may work, but it's hard to predict, and I don't know whether the behaviour is even documented. (Imagine if the evaluation holds on to the "current" element, and asks it for its next sibling each time - there won't be any more results when the element has been removed from the document!)

If you materialize the query first, it works fine:

foreach(var element in doc.Root.Elements("b").ToList())
{
    // Removed the pointless XElement.Parse call; it's cleaner just to create
    // an element with the data you want.
    element.ReplaceWith(new XElement("c", "fixed"));
}

Upvotes: 6

Related Questions