Как использовать HTML Agility Pack для редактирования фрагмента HTML

c# html-agility-pack

Вопрос

Поэтому у меня есть фрагмент 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. Как мне вернуть текстовую строку отредактированного объекта?

Принятый ответ

  1. То же, что и полный HTML-документ. Это не имеет значения.
  2. Возможны два варианта: вы можете напрямую редактировать свойство InnerHtml (или Text на текстовых узлах) или изменять дерево dom, используя, например, AppendChild , PrependChild и т. Д.
  3. Вы можете использовать свойство HtmlDocument.DocumentNode.OuterHtml или использовать метод HtmlDocument.Save (лично я предпочитаю второй вариант).

Что касается синтаксического анализа, я выбираю текстовые узлы, которые содержат поисковый string.Replace внутри вашего div , а затем просто используйте метод 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. Возможно, есть способ сделать это, но я не знаю, как это сделать. Я предлагаю загрузить весь документ.
  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);


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow