gpt4 book ai didi

c# - 为什么我的 C# Xml 代码仅在枚举变量 enumerable 时才起作用

转载 作者:行者123 更新时间:2023-12-02 19:25:48 24 4
gpt4 key购买 nike

我正在编写格式化 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 中的属性(通过将光标悬停在其上并查看元素计数),它确实有效。发现这一点后,我添加了

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
}

关于c# - 为什么我的 C# Xml 代码仅在枚举变量 enumerable 时才起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62412713/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com