Краткий ответ: из-за побочных эффектов при реализации XmlNodeList
.
XmlNode.SelectNodes()
возвращает XmlNodeList
(технически XPathNodeList
), что представляет собой «живой список» узлов, соответствующих выбору (в данном случае выбор XPath).
Когда вы повторяете XPathNodeList
или обращаетесь к нему другими способами, он проходит через совпадающие узлы, создание внутреннего списка по мере необходимости и возвращение их по мере необходимости. прошел через все. Итерация в основном преследует движущуюся цель по мере того, как документ перемещается под ней.
Однако, чтобы вернуть значение для свойства Count
, XPathNodeList
в основном необходимо найти каждый соответствующий узел и подсчитать их , поэтому он просматривает весь набор совпадений и помещает их все во внутренний список.
public override int Count {
get {
if (! done) {
ReadUntil(Int32.MaxValue);
}
return list.Count;
}
}
Я думаю, это объясняет то, что вы видите. Когда вы обращаетесь к свойству Count
перед внесением изменений, оно создает весь список узлов в качестве побочного эффекта, так что этот список все еще заполняется, когда вы фактически проходите по ним.
Конечно, это было бы неразумно полагаться на это недокументированное поведение.
Вместо этого я советую вам фактически скопировать содержимое XmlNodeList
в свой собственный список, а затем перебрать его:
string sFile = "PathFile";
XmlDocument doc = new XmlDocument();
doc.Load(sFile);
var allNodes = doc.DocumentElement
.SelectNodes("//*")
.OfType<XmlNode>() // using System.Linq;
.ToList();
foreach (XmlNode x in allNodes)
{
// rest of the code
}