Tho*_*asW 2 c# enumerate enumerable xml-attribute xmllist
我正在编写格式化 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 }
Run Code Online (Sandbox Code Playgroud)
现在我的代码工作正常,但只是有时,即使在两次运行之间没有改变任何东西。我已将范围缩小为:在 Visual Studio 中调试代码时,如果我只是从头到尾运行代码,则会出错。如果我中途中断并查看 XmlNodelist n 中的属性(通过将光标悬停在它上面并查看元素计数),它确实可以工作。发现这一点后,我添加了
int nCount = n.Count;
Run Code Online (Sandbox Code Playgroud)
行,现在代码从头到尾在无人监督的情况下运行。
这里发生了什么,解决这个问题的正确方法是什么?注意: doc.LoadXml 不适用于此特定文件。
谢谢你的负担,
托马斯
简短的回答:因为XmlNodeList.
XmlNode.SelectNodes()返回一个XmlNodeList(从技术上讲是 an XPathNodeList),它是与选择(在本例中为 XPath 选择)匹配的节点的“实时列表”。
当您XPathNodeList以其他方式迭代或访问它时,它会通过匹配的节点,根据需要构建内部列表,并根据需要返回它们。
因此,如果您在遍历节点时尝试重新排列文档,这可能会扰乱迭代并导致它在遍历所有节点之前停止。当文档在它下面移动时,迭代基本上是在追逐一个移动的目标。
但是,为了返回Count属性的值,XPathNodeList基本上需要找到每个匹配的节点并对其进行计数,因此它会遍历整个匹配集并将它们全部放入内部列表中。
public override int Count {
get {
if (! done) {
ReadUntil(Int32.MaxValue);
}
return list.Count;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这解释了你所看到的。当您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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
73 次 |
| 最近记录: |