我尝试使用一些已编辑的HTML替换我的根文档中的某些节点,但我收到错误:Collection was modified; perhaps enumeration operation is not performed. on parallel foreach
。我知道发生此错误是因为我正在修改循环内的原始结构。我怎么能这样做?我可以使用Parallel.ForEach
,还是只能使用普通foreach
?
这是我的代码:
Parallel.ForEach( blocks, block =>
{
var HtmlBlockDoc = new HtmlDocument();
HtmlBlockDoc.LoadHtml( block.Html );
var Node = HtmlDoc.DocumentNode.Descendants().FirstOrDefault( x => x.StreamPosition == block.Order );
if( Node != null )
Node.ParentNode.ReplaceChild( HtmlBlockDoc.DocumentNode, Node );
});
块var包含一些属性,但主要属性是Html
,这是我要在HtmlDoc.DocumentNode
和Order
StreamPosition that he currently is
上替换的html。我没有删除或添加新节点,我只是将<div></div>
替换为<div><p>My Parsed HTML</p></div>
。我使用HtmlAgilityPack来操纵HTML。
我也尝试克隆HtmlDoc.DocumentNode
,但我得到了同样的错误。
修改
我试图使用另一种方法来检索和替换所需的节点来解决此问题。如果我尝试使用HtmlDoc.DocumentNode.Descendants()
,我的搜索将在第一次替换后失败,因为它将更改原始结构。
怎么样?好吧,在Descendants
方法中,我得到所有Child Nodes
以及他们的Grand Childs Nodes
,好像它们处于同一级别一样,所以如果我在第一次替换时使用任何位置标识符,它将起作用,在第二次更换时,它不会因为我添加了更多节点而且这些节点也将被添加到Descendants
的{{1}}列表中。
在发现我看到我可以使用ChildNodes之后,它将遵循三者的真实结构。要做到这一点,我将得到每个孩子,寻找我的节点和:
我知道我需要使用递归函数来实现这一点,但我在如何做到这一点时遇到了一些问题。这是我修改过的代码:
DocumentNode
如果有人想要重新创建问题,我在此处发布了原始HTML:PasteBin