次の XML があります。
<Parts>
<Part name="Part1" disabled="true"></Part>
<Part name="Part2" disabled="false"></Part>
<Part name="Part3" ></Part>
<Part name="Part4" disabled="true"></Part>
</Parts>
disabled
属性が に設定されているノードを削除したいtrue
。'disabled' 属性がどの 'Part' 要素にも使用されていない場合、それは無効になっていないことを意味します。
私は次のコードを書きました:
XmlNode root = xmlDoc.DocumentElement;
List<XmlNode> disabledNodes = new List<XmlNode>();
foreach(XmlNode node in root.ChildNodes)
{
if(node.Attributes["disabled"] != null &&
Convert.ToBoolean(node.Attributes["disabled"].Value))
{
disabledNodes.Add(node);
}
}
foreach (XmlNode node in disabledNodes)
{
root .RemoveChild(node);
}
このコードは、予想どおり XML から 2 つのノードを削除します。
次に、コードをコンパクトにするために次のコードを書きました。
foreach (XmlNode node in root.ChildNodes.Cast<XmlNode>()
.Where(child => child.Attributes["disabled"] != null &&
Convert.ToBoolean(child.Attributes["disabled"].Value)))
{
root.RemoveChild(node); // This line works fine without any exception.
}
このループは 1 回だけ繰り返され、XML からノードが 1 つだけ削除されることがわかりました。
編集された質問:
foreach
ループを変更すると、今度は LINQ 式の結果をList<T>
usingToList()
メソッドに変換します (@Toni Petrina の回答で提案されているように)。そして今回はうまくいきました!
foreach (XmlNode node in root.ChildNodes.Cast<XmlNode>()
.Where(child => child.Attributes["disabled"] != null &&
Convert.ToBoolean(child.Attributes["disabled"].Value)).ToList())
{
root.RemoveChild(node); // This line works fine without any exception.
}
ToList()
作成されたLINQ式の使用がforeach
ループで期待どおりに機能するのはなぜですか? LINQ の結果が 2 つの異なる状況で異なる動作をする技術的な理由はありますか?
.NET 4.0 を使用しています。