替换 xml 元素
我正在做类似的事情:
var results = from d in myDocument.Elements().Descendants("myName") select d;
foreach (var result in results){
if (sth...){
result.replace(myXElement);
}
}
问题是,当我替换一个元素时,我无法迭代到下一个元素,因为存在空引用。 (结果中的变量结果)。
是否有其他方法可以将该元素替换为另一个元素,并且仍然能够迭代该文档?
感谢您的帮助,
堆栈跟踪是:
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:
Im doing something like that:
var results = from d in myDocument.Elements().Descendants("myName") select d;
foreach (var result in results){
if (sth...){
result.replace(myXElement);
}
}
The problem is that when I replace an element I cant iterate to the next element cause there is null reference. (var result in results).
Is there any other way to replace that element with another one and still be able to iterate through that document ?
thanks for help
the stacktrace is:
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:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
循环访问 IEnumerable 时无法对其进行修改。
由于 LINQ to XML 使用延迟执行,因此它会在您修改 XML 时尝试查找后代。
要解决此问题,您需要在循环之前将元素放入数组中,如下所示:
通过调用 ToArray(),您可以强制它立即枚举元素,而不是在循环时查找它们通过他们。
You cannot modify an IEnumerable while looping through it.
Since LINQ to XML uses deferred execution, it's trying to find the descendants as you modify the XML.
To fix this, you need to put the elements in an array before looping through them, like this:
By calling
ToArray()
, you force it to enumerate through the elements immediately instead of finding them as you loop through them.看来您已经推出了自己的扩展方法
replace(myXElement)
。但似乎 XNode.ReplaceWith 方法(对象) 在这种情况下可以满足您的需求。以下是 Microsoft 的
ReplaceWith(Object)
示例,摘自其文档:== 代码 ==
== 预期输出 ==
It appears you have rolled your own Extension Method
replace(myXElement)
. But it seems that XNode.ReplaceWith Method (Object) would serve your need in this situation.Here's Microsoft's example for
ReplaceWith(Object)
taken from its documentation:== Code ==
== Expected Output ==