2012-03-01 12 views
11

Así que tengo un fragmento de HTML que quiero modificar con C#.¿Cómo uso HTML Agility Pack para editar un fragmento de HTML?

<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 HTML agilidad componentes a base de las muchas recomendaciones aquí, pero no sé donde voy . En particular,

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

Respuesta

17
  1. lo mismo que un documento HTML completo. No importa.
  2. Las son 2 opciones: puede editar la propiedad InnerHtml directamente (o Text en los nodos de texto) o modificar el árbol dom usando, p. Ej. AppendChild, 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 su div, y luego sólo tiene que utilizar string.Replace método 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 guardar el resultado en una cadena:

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

Gracias. Múltiples opciones Una cosa que sí aprendí jugando con la manipulación DOM es la utilidad del siguiente código: node.ParentNode.ReplaceChild (newNode, node) – John

+0

HtmlDocument.DocumentNode.OuterHtml devuelve null y doc.Save() da StackOverflowException ¿Cómo puedo resolverlo? –

+0

@NavinGupta tal vez, tiene nodos de autorreferencia – Alex

1

Respuestas:

  1. Puede haber una manera de hacer esto, pero yo no sé cómo. Sugiero cargando el documento completo.
  2. Utilice una combinación de expresiones XPath y regulares
  3. Consulte el siguiente código para obtener un ejemplo artificial. Puede tener otras restricciones no mencionadas, pero este ejemplo de código debe hacer que se inicie .

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

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