簡體   English   中英

為什么我的 C# Xml 代碼僅在我枚舉變量可枚舉時才有效

[英]Why does my C# Xml code only work when I enumerate variable enumerable

我正在處理格式化 XML 文件的代碼,以便子文件夾節點實際上嵌套在其父節點中。 源 XML 將每個文件夾作為根中的單獨子節點而不是正確的樹,因為您期望它在其主文件夾中具有子文件夾。 這個問題的代碼是關於:

// Load original XML

string sFile = "PathFile";
XmlDocument doc = new XmlDocument();
doc.Load(sFile);

var n = doc.DocumentElement.SelectNodes ("//*");   // Load all nodes into nodelist n
// int nCount = n.Count;                           // If uncommented code works

foreach(XmlNode x in n)
{ rest of the code }

現在我的代碼可以正常工作,但只是有時,即使在兩次運行之間沒有更改任何內容。 我已將其縮小為:在 Visual Studio 中調試代碼時,如果我只是從頭到尾運行代碼,則會出錯。 如果我中斷並查看 XmlNodelist n 中的屬性(通過將 cursor 懸停在它上面並查看元素計數)它確實有效。 發現這一點后,我添加了

int nCount = n.Count; 

行,現在代碼從頭到尾在無人監督的情況下運行。

這里發生了什么,解決這個問題的正確方法是什么? 注意: doc.LoadXml 不適用於此特定文件。

謝謝你的負載,

托馬斯

簡短的回答:因為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 
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM