如何使用HTML Agility Pack编辑HTML片段

19

所以我有一个 HTML 片段,我想用 C# 进行修改。

<div>
This is a specialSearchWord that I want to link to
<img src="anImage.jpg" />
<a href="foo.htm">A hyperlink</a>
Some more text and that specialSearchWord again.
</div>

我想把它转换成这个样子:

<div>
This is a <a class="special" href="http://mysite.com/search/specialSearchWord">specialSearchWord</a> that I want to link to
<img src="anImage.jpg" />
<a href="foo.htm">A hyperlink</a>
Some more text and that <a class="special" href="http://mysite.com/search/specialSearchWord">specialSearchWord</a> again.
</div>

我决定基于这里的许多建议使用HTML Agility Pack,但我不知道该怎么做。具体来说:

  1. 如何将部分片段作为字符串加载,而不是整个HTML文档?
  2. 如何编辑?
  3. 编辑后如何返回已编辑对象的文本字符串?
2个回答

30
  1. 和完整的HTML文档一样。无关紧要。
  2. 有两个选项:您可以直接编辑InnerHtml属性(或文本节点上的Text),也可以通过使用AppendChildPrependChild等修改DOM树。
  3. 您可以使用HtmlDocument.DocumentNode.OuterHtml属性或使用HtmlDocument.Save方法(个人更喜欢第二个选项)。

至于解析,我选择选择包含搜索词的文本节点,然后只需使用string.Replace方法来替换它:

var doc = new HtmlDocument();
doc.LoadHtml(html);
var textNodes = doc.DocumentNode.SelectNodes("/div/text()[contains(.,'specialSearchWord')]");
if (textNodes != null)
    foreach (HtmlTextNode node in textNodes)
        node.Text = node.Text.Replace("specialSearchWord", "<a class='special' href='http://mysite.com/search/specialSearchWord'>specialSearchWord</a>");

并将结果保存到字符串中:

string result = null;
using (StringWriter writer = new StringWriter())
{
    doc.Save(writer);
    result = writer.ToString();
}

1
谢谢。多种选择。玩弄DOM操作时我学到的一件事是以下代码的用处:node.ParentNode.ReplaceChild(newNode, node)。 - John
HtmlDocument.DocumentNode.OuterHtml返回null,而doc.Save()会导致StackOverflowException。我该如何解决? - Navin Gupta
@NavinGupta 也许你有自引用节点。 - Oleks

2

答案:

  1. 可能有一种方法可以实现,但我不知道如何操作。我建议加载整个文档。
  2. 使用XPath和正则表达式的组合。
  3. 查看下面的代码以获取一个不真实的示例。您可能有其他未提及的限制,但此代码示例应该可以帮助您入门。

请注意,您的XPath表达式可能需要更复杂才能找到您想要的div。

HtmlDocument doc = new HtmlDocument();

doc.Load(yourHtmlFile);
HtmlNode divNode = doc.DocumentNode.SelectSingleNode("//div[2]");
string newDiv = Regex.Replace(divNode.InnerHtml, @"specialSearchWord", 
"<a class='special' href='http://etc'>specialSearchWord</a>");
divNode.InnerHtml = newDiv;
Console.WriteLine(doc.DocumentNode.OuterHtml);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接