Replace xml element

I am doing something like this:

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 cannot iterate over the next element because there is a null reference. (var produces the results).

Is there any other way to replace this element with another and still be able to iterate over this document?

thanks for the help

stack:

  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: 
+4
source share
2 answers

You cannot modify IEnumerable while passing through it.

Since LINQ to XML uses deferred execution, it tries to find children when XML changes.

To fix this, you need to put the elements in an array before going through them, for example:

 var results = myDocument.Descendants("myName").ToArray(); foreach (var result in results){ if (sth...){ result.replace(myXElement); } } 

By calling ToArray() , you force it to list through the elements immediately, rather than finding them when you project them.

+3
source

You seem to have implemented your own replace(myXElement) extension method replace(myXElement) . But it seems that XNode.ReplaceWith Method (Object) will serve your needs in this situation.

Here is a Microsoft example for ReplaceWith(Object) , taken from its documentation:

== Code ==

 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); 

== Expected Result ==

 <Root> <Child1>child1 content</Child1> <Child2>child2 content</Child2> <NewChild>new content</NewChild> <Child4>child4 content</Child4> <Child5>child5 content</Child5> </Root> 
0
source

Source: https://habr.com/ru/post/1312141/


All Articles