Come utilizzare HTML Agility Pack per modificare uno snippet HTML

c# html-agility-pack

Domanda

Quindi ho uno snippet HTML che voglio modificare 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>

e voglio trasformarlo in questo:

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

Userò HTML Agility Pack sulla base dei numerosi consigli qui, ma non so dove sto andando. In particolare,

  1. Come carico uno snippet parziale come stringa, invece di un documento HTML completo?
  2. Come si modifica?
  3. Come posso quindi restituire la stringa di testo dell'oggetto modificato?

Risposta accettata

  1. Lo stesso di un documento HTML completo. Non importa.
  2. Le opzioni sono 2: puoi modificare direttamente la proprietà InnerHtml (o Text sui nodi di testo) o modificare l'albero delle dom usando, ad esempio, AppendChild , PrependChild ecc.
  3. È possibile utilizzare la proprietà HtmlDocument.DocumentNode.OuterHtml o utilizzare il metodo HtmlDocument.Save (personalmente preferisco la seconda opzione).

Per quanto riguarda l'analisi, seleziono i nodi di testo che contengono il termine di ricerca all'interno del tuo div , e quindi uso solo il metodo string.Replace per sostituirlo:

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

E salvando il risultato in una stringa:

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

Risposta popolare

risposte:

  1. Potrebbe esserci un modo per farlo, ma non so come. Suggerisco di caricare l'intero documento.
  2. Usa una combinazione di XPath ed espressioni regolari
  3. Vedere il codice qui sotto per un esempio forzato. Potresti avere altri vincoli non menzionati ma questo esempio di codice dovrebbe farti iniziare.

Nota che l'espressione Xpath potrebbe dover essere più complessa per trovare il div che desideri.

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

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché