HTMLAgilityPack错误:“无法创建多个节点元素。”

时间:2018-11-16 14:24:36

标签: c# html regex

我正在尝试使用HTMLAgilityPack来获取和编辑某些HTML的内部文本。我需要检查我检索到的每个节点的内部文本是否包含匹配的字符串,并突出显示那些匹配的字符串,如下所示:

var HtmlDoc = new HtmlDocument();
HtmlDoc.LoadHtml(item.Content);

var nodes = HtmlDoc.DocumentNode.SelectNodes("//div[@class='guide_subtitle_cell']/p");
foreach (HtmlNode htmlNode in nodes)
{
    htmlNode.ParentNode.ReplaceChild(HtmlTextNode.CreateNode(Methods.HighlightWords(htmlNode.InnerText, searchstring)), htmlNode);
}

这是我使用的HighlightWords方法的代码:

public static string HighlightWords(string input, string searchstring)
    {
        if (input == null || searchstring == null)
        {
            return input;
        }

        var lowerstring = searchstring.ToLower();
        var words = lowerstring.Split(' ').ToList();

        for (var i = 0; i < words.Count; i++)
        {
            Match m = Regex.Match(input, words[i], RegexOptions.IgnoreCase);

            if (m.Success)
            {
                string ReplaceWord = string.Format("<span class='search_highlight'>{0}</span>", m.Value);
                input = Regex.Replace(input, words[i], ReplaceWord, RegexOptions.IgnoreCase);
            }
        }

        return input;
}

有人可以建议如何使它正常工作或指出我在做什么错吗?

2 个答案:

答案 0 :(得分:0)

问题是HtmlTextNode.CreateNode只能创建一个节点。当您在内部添加<span>时,这是另一个节点,并且CreateNode会引发您看到的异常。

确保仅在最低叶节点(没有子节点的节点)上进行搜索和替换。然后通过以下方式重建该节点:

  1. 创建一个新的空节点来替换旧的
  2. 搜索.InnerText中的文本
  3. 使用HtmlTextNode.Create在要突出显示的文本之前 添加纯文本
  4. 然后使用<span>添加新的HtmlNode.CreateNode和突出显示的文本
  5. 然后搜索下一个事件(从1开始),直到找不到更多的事件为止。

答案 1 :(得分:0)

您的功能HighlightWords必须返回多个顶级HTML节点。例如:

<p>foo</p>
<span>bar</span>

HtmlAgilityPack仅允许返回一个顶级节点。您可以对HighlightWords的返回值进行硬编码以进行测试。

此外,this post遇到了同样的问题。