Попытка исправить неправильную разметку HTML.

Допустим, у меня есть следующая разметка:

<li>Foo</li>
<li>Bar</li>

Или

<li>Foo</li>
<li>Bar</li>
</ul>

Или

<ul>
<li>Foo</li>
<li>Bar</li>

Кроме того, до или после списка может быть текст.

Что я пробовал:

HtmlNode firstLiNode = doc.DocumentNode.ChildNodes.FirstOrDefault(n => n.Name.Equals("li"));
if (firstLiNode != null &&
    (firstLiNode.PreviousSibling == null || !firstLiNode.PreviousSibling.Name.Equals("ul")))
{
    doc.DocumentNode.InsertBefore(HtmlNode.CreateNode("<ul>"), firstLiNode);
}

Который, на мой взгляд, должен просто добавить тег <ul> перед первым тегом <li>. Следуя той же логике, я мог бы при необходимости вставить </ul> в конец списка, но вместо этого я получаю <ul></ul><li>Foo</li><li>Bar</li>, даже не пытаясь вставить закрывающий тег ul.

Вопрос: Что я делаю не так?

0
Ed T. 14 Ноя 2019 в 17:42
1
"doc.DocumentNode.InsertBefore (HtmlNode.CreateNode ("
    "), firstLiNode);" Вставляет его перед. Вы должны сделать это, и после копирования li внутри ul.
 – 
Emanuele
14 Ноя 2019 в 17:52

1 ответ

Лучший ответ

Мое решение было следующее:

Удаление всех тегов UL, а затем вставка нового, если необходимо, следующим образом:

HtmlNode firstLiNode = pos.Nodes.FirstOrDefault(n => n.Name.Equals("li"));
if (firstLiNode != null)
{
    // Retrieve all LI nodes that should be wrapped with the UL tag.
    IEnumerable<HtmlNode> liNodes = doc.DocumentNode.SelectNodes(@"//li");
    HtmlNode ulNode = HtmlNode.CreateNode("<ul>");

    // Insert LI tags into newly created UL tag.
    foreach (HtmlNode liNode in liNodes)
    {
        HtmlNode clone = liNode.CloneNode(true);
        ulNode.AppendChild(clone);
    }

    // Insert newly created UL tag with child LI nodes before "original" LI tag without UL tag.
    doc.DocumentNode.InsertBefore(ulNode, firstLiNode);

    // Remove LI tags that are not wrapped with UL tag.
    foreach (HtmlNode liNode in liNodes)
    {
        doc.DocumentNode.RemoveChild(liNode);
    }
}
1
Ed T. 5 Фев 2020 в 14:28