title: HtmlAgility edit HtmlNode inside foreach
body: <p>I'm trying to replace some nodes inside my root document with some edited HTML but i'm getting an error: <code>Collection was modified; perhaps enumeration operation is not performed. on parallel foreach</code>. I know this error occurs because i'm modifying the original structure inside a loop. How could i do it ? Can i use <code>Parallel.ForEach</code> or i have to only use a normal <code>foreach</code>?</p>
  
  <p>This is my code:</p>
  
  <pre><code>Parallel.ForEach( blocks, block =&gt;
  {
      var HtmlBlockDoc = new HtmlDocument();
  
      HtmlBlockDoc.LoadHtml( block.Html );
  
      var Node = HtmlDoc.DocumentNode.Descendants().FirstOrDefault( x =&gt; x.StreamPosition == block.Order );
  
      if( Node != null )
          Node.ParentNode.ReplaceChild( HtmlBlockDoc.DocumentNode, Node );
  });
  </code></pre>
  
  <p>The block var contains some attributes but the main ones are <code>Html</code> that is the html i want to replace on the <code>HtmlDoc.DocumentNode</code> and <code>Order</code> that is the <code>StreamPosition that he currently is</code>. I'm not removing nor adding new nodes, i'm just replacing a <code>&lt;div&gt;&lt;/div&gt;</code> by <code>&lt;div&gt;&lt;p&gt;My Parsed HTML&lt;/p&gt;&lt;/div&gt;</code> for example. I'm using <a href="https://www.nuget.org/packages/HtmlAgilityPack" rel="nofollow">HtmlAgilityPack</a> to manipulate the HTML.</p>
  
  <p>I have also tried to clone the <code>HtmlDoc.DocumentNode</code> but i got the same error.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I'm trying to solve this problem using another method to retrieve and replace the desired nodes. If i try to use <code>HtmlDoc.DocumentNode.Descendants()</code> my search will fail after the first replace because it will change the original structure. </p>
  
  <p>How ? Well, in the <code>Descendants</code> method i get all the <code>Child Nodes</code> and also their <code>Grand Childs Nodes</code> as if they were in the same level, so if i use any position identifier on the first replacement it will work, on the second replacement it won't because i have added more nodes and those nodes will also be added to the list of <code>Descendants</code> of the <code>DocumentNode</code>.</p>
  
  <p>After discovering that i saw i could use ChildNodes since it will follow the real structure of the three. To do that i will have to get each child, look for my node and:</p>
  
  <ul>
  <li>If i find it: replace and continue the foreach;</li>
  <li>If i don't find it: get the next child node or get the next sibling and look inside his child for my node</li>
  </ul>
  
  <p>I know i need to use a recursive function to achieve that but i'm having some problems on how to do it. This is my modified code:</p>
  
  <pre><code>var HtmlDoc = new HtmlDocument { OptionFixNestedTags = true };
  HtmlDoc.LoadHtml( "My HTML" );
  
  foreach( var block in blocks )
  {
      var HtmlBlockDoc = new HtmlDocument();
  
      HtmlBlockDoc.LoadHtml( block.Html.CleanHTML( false ).ReplaceWhiteSpaceTags() );
  
      ReplaceHtmlNode( HtmlDoc, block );
  }
  
  private static List&lt;HtmlNode&gt; ReplaceHtmlNode( HtmlDocument htmlDoc, TemplateBlock block )
  {
      var Node = htmlDoc.DocumentNode.ChildNodes.FirstOrDefault( x =&gt; x.XPath.Equals( block.XPath ) );
  
      if( Node != null )
          Node.ParentNode.ReplaceChild( htmlDoc.DocumentNode, Node );
      else
      {
          //How to do it and how to know when to leave ?
          ReplaceHtmlNode(  )
      }
  }
  </code></pre>
  
  <p>I posted my original HTML here if anyone wants it to recreate the problem: <a href="http://pastebin.com/p1unLB9a" rel="nofollow">PasteBin</a></p>