Comment nettoyer du HTML mal formé à l'aide de HTML Agility Pack

asp.net c# html html-agility-pack

Question

J'essaie de remplacer cette incroyable collection d'expressions régulières qui est actuellement utilisée pour nettoyer des blocs de HTML mal formé et qui est tombé sur le HTML Agility Pack for C #. Cela a l'air très puissant, mais je ne pouvais pas trouver d'exemple illustrant la manière dont je voulais utiliser le pack, qui, selon moi, constituerait une fonctionnalité souhaitée. Je suis sûr que je suis un idiot et que je ne trouve pas de méthode appropriée dans la documentation.

Laissez-moi vous expliquer ... disons que j'avais le code HTML suivant:

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

... que je veux ressembler à:

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

Lorsque j'utilise la méthode HtmlNode.Remove (), elle supprime le nœud et tous ses enfants. Existe-t-il un moyen de supprimer le nœud en préservant les enfants?

Merci :)

Réponse acceptée

Sur HtmlNode, la méthode RemoveChild a cette surcharge:

public HtmlNode RemoveChild(HtmlNode oldChild, bool keepGrandChildren);

Alors voici comment vous le feriez:

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

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

EDIT: Il semble que l'option Remplacer avec keepGrandChildren ne fonctionne pas comme prévu. Voici donc une autre implémentation:

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

Réponse populaire

Vous pouvez essayer d'utiliser 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();
}


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi