我正在做类似的事情:
var results = from d in myDocument.Elements().Descendants("myName") select d;
foreach (var result in results){
if (sth...){
result.replace(myXElement);
}
}
问题在于,当我替换一个元素时,我无法迭代到下一个元素,因为存在空引用。 (结果导致结果)。
有没有其他方法可以将该元素替换为另一个元素,并且仍然能够遍历该文档?
感谢您的帮助
stacktrace是:
System.NullReferenceException was unhandled Message="Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu." Source="System.Xml.Linq" StackTrace: w System.Xml.Linq.XContainer.d__a.MoveNext() w System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext() w DocSorter.Merge.MergeFiles(String contentFilePath, String directoryPath) w D:\DocSorter\DocSorter\Merge.cs:wiersz 39 w DocSorter.MainBox.btnMergeFiles_Click(Object sender, EventArgs e) w D:\DocSorter\DocSorter\MainBox.cs:wiersz 85 w System.Windows.Forms.Control.OnClick(EventArgs e) w System.Windows.Forms.Button.OnClick(EventArgs e) w System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) w System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) w System.Windows.Forms.Control.WndProc(Message& m) w System.Windows.Forms.ButtonBase.WndProc(Message& m) w System.Windows.Forms.Button.WndProc(Message& m) w System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) w System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) w System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) w System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) w System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) w System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) w System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) w System.Windows.Forms.Application.Run(Form mainForm) w DocSorter.Program.Main() w D:\DocSorter\DocSorter\Program.cs:wiersz 18 w System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) w System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() w System.Threading.ThreadHelper.ThreadStart_Context(Object state) w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) w System.Threading.ThreadHelper.ThreadStart() InnerException:
答案 0 :(得分:3)
循环浏览IEnumerable时无法修改它。
由于LINQ to XML使用延迟执行,因此在修改XML时会尝试查找后代。
要解决此问题,您需要在循环之前将元素放在数组中,如下所示:
var results = myDocument.Descendants("myName").ToArray();
foreach (var result in results){
if (sth...){
result.replace(myXElement);
}
}
通过调用ToArray()
,您可以强制它立即枚举元素,而不是在循环浏览时找到它们。
答案 1 :(得分:0)
您似乎已经推出了自己的扩展方法replace(myXElement)
。但在这种情况下,XNode.ReplaceWith Method (Object)似乎可以满足您的需求。
以下是Microsoft的ReplaceWith(Object)
示例,摘自其文档:
==代码==
XElement xmlTree = new XElement("Root",
new XElement("Child1", "child1 content"),
new XElement("Child2", "child2 content"),
new XElement("Child3", "child3 content"),
new XElement("Child4", "child4 content"),
new XElement("Child5", "child5 content")
);
XElement child3 = xmlTree.Element("Child3");
child3.ReplaceWith(
new XElement("NewChild", "new content")
);
Console.WriteLine(xmlTree);
==预期输出==
<Root>
<Child1>child1 content</Child1>
<Child2>child2 content</Child2>
<NewChild>new content</NewChild>
<Child4>child4 content</Child4>
<Child5>child5 content</Child5>
</Root>