HtmlAgilityPack - Добавить узел - PullRequest
0 голосов
/ 23 января 2019

Я пытался добавить новый узел в Html, используя Html Agility Pack.

Это мой образец HTML

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>
        </title>
        <style type="text/css">
            .csDBEB299A{text-align:left;text-indent:0pt;margin:0pt 0pt 0pt 0pt;line-height:14.65pt;mso-line-height-rule:exactly}
            .cs15323895{color:#000000;background-color:transparent;font-family:Verdana;font-size:10pt;font-weight:normal;font-style:normal;}
        </style>
    </head>
    <body>
        <p class="csDBEB299A"><span class="cs15323895">This is a sample</span></p><p class="csDBEB299A"><span class="cs15323895">&nbsp;</span></p><p class="csDBEB299A"><span class="cs15323895">&nbsp;</span></p><p class="csDBEB299A"><span class="cs15323895">Table name: Table 1</span></p><p class="csDBEB299A"><span class="cs15323895">&nbsp;</span></p><p class="csDBEB299A"><a name="_GoBack"></a><span class="cs15323895">&nbsp;</span></p></body>
</html>

Условие - если innerHtml начинается с "Table name:", к нему должен быть добавлен узел.

Например, у меня есть это

<span class="cs15323895">Table name: Table 1</span>

станет

<span class="cs15323895">Table name: Table 1<h2>This is h2 heading</h2></span>

А вот документация о том, как добавить ребенка с помощью Html Agility Pack

https://html-agility-pack.net/append-child

А вот и мой код

                var htmlDoc = new HtmlDocument();
                htmlDoc.Load(htmlFile);

                foreach (var item in htmlDoc.DocumentNode.Descendants())
                {
                    if (!item.HasChildNodes)
                    {
                        var text = item.InnerHtml;
                        var textTosearch = "table name:";
                        if (text.ToLower().StartsWith(textTosearch))
                        {

                            HtmlNode h2Node = HtmlNode.CreateNode("<h2> This is h2 heading</h2>");
                            item.AppendChild(h2Node);
                        }
                    }
                }

Но при сохранении в файл я получаю сообщение об ошибке

        htmlDoc.Save(@"test.html");

А ниже приведена ошибка:

Process is terminated due to StackOverflowException.
An unhandled exception of type 'System.StackOverflowException'

Я искал решение, но решение, предложенное в другом вопросе, не работает с моей проблемой.

Я попытался поймать, но это не дает мне строку, где он обнаружил ошибку. Спасибо

1 Ответ

0 голосов
/ 23 января 2019

htmlDoc.DocumentNode.Descendants() возвращает не только обычные элементы, такие как span, div и т. Д., Но также возвращает специальные text элементы, представляющие любой текст внутри html элементов.

Вам необходимодобавить дочерний узел к элементу span.Но вы фактически добавляете его к элементу text, который является дочерним узлом элемента span.По какой-то причине HtmlAgilityPack завершается неудачно, если к элементу text добавлен дочерний элемент.

Таким образом, необходимо удалить условие if (!item.HasChildNodes), поскольку целевой элемент имеет дочерний элемент text и исключает textэлементы.Примерно так должно работать:

foreach (var item in htmlDoc.DocumentNode.Descendants())
{
    if (item.NodeType != HtmlNodeType.Text)
    {
        var text = item.InnerHtml;
        var textTosearch = "table name:";
        if (text.ToLower().StartsWith(textTosearch))
        {

            HtmlNode h2Node = HtmlNode.CreateNode(@"<h2> This is h2 heading</h2>");
            item.AppendChild(h2Node);
        }
    }
}
...