Come ripulire l'HTML mal formato utilizzando l'HTML Agility Pack

asp.net c# html html-agility-pack

Domanda

Sto tentando di rimpiazzare questa terribile collezione di espressioni regolari attualmente utilizzata per ripulire blocchi di HTML mal formato e incappare in HTML Agility Pack per C #. Sembra molto potente, ma non riesco a trovare un esempio di come voglio usare il pacchetto che, a mio avviso, sarebbe una funzionalità desiderata inclusa in esso. Sono sicuro di essere un idiota e non riesco a trovare un metodo adatto nella documentazione.

Lasciami spiegare ... dimmi che ho il seguente codice HTML:

<p class="someclass">
    <font size="3">
        <font face="Times New Roman">
            this is some text
            <a href="somepage.html">Some link</a>
        </font>
    </font>
</p>

... che voglio assomigliare a:

<p>
    this is some text
    <a href="somepage.html">Some link</a>
</p>

Quando utilizzo il metodo HtmlNode.Remove () rimuove il nodo più tutti i suoi figli. C'è un modo per rimuovere il nodo preservando i bambini?

Grazie :)

Risposta accettata

Su HtmlNode, il metodo RemoveChild ha questo sovraccarico:

public HtmlNode RemoveChild(HtmlNode oldChild, bool keepGrandChildren);

Quindi questo è come lo faresti:

HtmlDocument doc = new HtmlDocument();
doc.Load("yourfile.htm");

foreach (HtmlNode font in doc.DocumentNode.SelectNodes("//font"))
{
    font.ParentNode.RemoveChild(font, true);
}

EDIT: Sembra che l'opzione Replace w / keepGrandChildren non funzioni come previsto, quindi ecco un'implementazione alternativa:

public static HtmlNode RemoveChild(HtmlNode parent, HtmlNode oldChild, bool keepGrandChildren)
{
    if (oldChild == null)
        throw new ArgumentNullException("oldChild");

    if (oldChild.HasChildNodes && keepGrandChildren)
    {
        HtmlNode prev = oldChild.PreviousSibling;
        List<HtmlNode> nodes = new List<HtmlNode>(oldChild.ChildNodes.Cast<HtmlNode>());
        nodes.Sort(new StreamPositionComparer());
        foreach (HtmlNode grandchild in nodes)
        {
            parent.InsertAfter(grandchild, prev);
        }
    }
    parent.RemoveChild(oldChild);
    return oldChild;
}

// this helper class allows to sort nodes using their position in the file.
private class StreamPositionComparer : IComparer<HtmlNode>
{
    int IComparer<HtmlNode>.Compare(HtmlNode x, HtmlNode y)
    {
        return y.StreamPosition.CompareTo(x.StreamPosition);
    }
}

Risposta popolare

Potresti provare a utilizzare AngleSharp https://github.com/AngleSharp/AngleSharp

var parser = new HtmlParser();
var document = parser.Parse(html);

using (var writer = new StringWriter())
{
    document.ToHtml(writer, new PrettyMarkupFormatter());
    return writer.ToString();
}


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é