¿Cómo uso HTML Agility Pack para editar un fragmento de código HTML?

c# html-agility-pack

Pregunta

Así que tengo un fragmento de código HTML que quiero modificar usando 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>

Y quiero transformarlo a esto:

<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>

Voy a usar el paquete de agilidad HTML basado en las muchas recomendaciones aquí, pero no sé a dónde voy. En particular,

  1. ¿Cómo puedo cargar un fragmento parcial como una cadena, en lugar de un documento HTML completo?
  2. ¿Cómo editar?
  3. ¿Cómo devuelvo la cadena de texto del objeto editado?

Respuesta aceptada

  1. Lo mismo que un documento HTML completo. No importa.
  2. Las opciones son 2: puede editar la propiedad InnerHtml directamente (o Text en los nodos de texto) o modificar el árbol de AppendChild utilizando, por ejemplo, PrependChild , PrependChild , etc.
  3. Puede usar la propiedad HtmlDocument.DocumentNode.OuterHtml o usar el método HtmlDocument.Save (personalmente prefiero la segunda opción).

En cuanto al análisis, selecciono los nodos de texto que contienen el término de búsqueda dentro de tu div , y luego solo uso el método string.Replace para reemplazarlo:

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>");

Y guardando el resultado en una cadena:

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

Respuesta popular

Respuestas:

  1. Puede haber una manera de hacer esto, pero no sé cómo. Sugiero cargar todo el documento.
  2. Usa una combinación de XPath y expresiones regulares
  3. Ver el código de abajo para un ejemplo artificial. Es posible que tenga otras restricciones no mencionadas, pero este ejemplo de código debería ayudarlo a comenzar.

Tenga en cuenta que su expresión Xpath puede necesitar ser más compleja para encontrar el div que desea.

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);


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué