Как очистить плохо сформированный HTML с помощью HTML Agility Pack - PullRequest
8 голосов
/ 21 марта 2011

Я пытаюсь заменить эту ужасную коллекцию регулярных выражений, которая в настоящее время используется для очистки блоков плохо сформированного HTML и наткнулась на пакет Agility HTML для C #. Это выглядит очень мощно, но пока я не смог найти пример того, как я хочу использовать пакет, который, на мой взгляд, был бы желаемой функциональностью, включенной в него. Я уверен, что я идиот и не могу найти подходящий метод в документации.

Позвольте мне объяснить ... скажем, у меня был следующий 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>

... что я хочу выглядеть:

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

Когда я использую метод HtmlNode.Remove (), он удаляет узел и все его дочерние элементы. Есть ли способ удалить узел, сохраняющий дочерние элементы?

Ответы [ 3 ]

7 голосов
/ 21 марта 2011

На HtmlNode метод RemoveChild имеет следующую перегрузку:

public HtmlNode RemoveChild(HtmlNode oldChild, bool keepGrandChildren);

Так вот, как бы вы это сделали:

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

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

РЕДАКТИРОВАТЬ: Похоже, опция Replace w / keepGrandChildren работает не так, как ожидалось, поэтому есть альтернативная реализация:

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);
    }
}
2 голосов
/ 18 января 2018

Вместо этого вы можете попробовать AngleSharp .

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

using (var writer = new StringWriter())
{
    document.ToHtml(writer, new PrettyMarkupFormatter());
    return writer.ToString();
}
0 голосов
/ 21 марта 2011

Как только вы найдете элемент

, используйте метод InnerText для получения текста, затем выполните удаление и вставьте текст.

...