HTML Agility pack удаляет тег break close

Я создаю HTML-документ, используя пакет гибкости HTML. Я загружаю файл шаблона, а затем добавляю его в него. Все это работает, но когда я просматриваю выходной файл, он удаляет закрывающий тег из тегов <br/>, чтобы выглядеть так: <br>. Что вызывает это?

Dim doc As New HtmlDocument()
doc.Load(Server.MapPath("Template.htm"))

Dim title As HtmlNode = doc.DocumentNode.SelectSingleNode("//title")

title.InnerHtml = title.InnerHtml & "CEU Classes"
Dim topContent As HtmlAgilityPack.HtmlNode = doc.GetElementbyId("topContent")

topContent.InnerHtml = html.ToString
doc.OptionWriteEmptyNodes = True
doc.Save(outputFileName, Encoding.UTF8)

Дополнительная информация:

Он удалял мои закрывающие теги изображений, после того как я добавил doc.OptionWriteEmptyNodes = True, он это делает.

Обновить

Теперь это мой код, который удаляет закрывающий тег BR

Dim html As String = "Words<br/>more words"
Dim doc As New HtmlDocument()
Dim title As HtmlNode
Dim topContent As HtmlNode

HtmlNode.ElementsFlags("br") = HtmlElementFlag.Empty
doc.Load(Server.MapPath("Template.htm"))

Title = doc.DocumentNode.SelectSingleNode("//title")
title.InnerHtml = title.InnerHtml & "CEU Classes"

topContent = doc.GetElementbyId("topContent")
topContent.InnerHtml = html.ToString

doc.OptionWriteEmptyNodes = True
doc.Save(outputFileName, Encoding.UTF8)

Обновление 2

В итоге я просто прочитал в своем файле шаблона стандартную строку, а затем загрузил html, как этот

Dim TemplateHTML As String = File.ReadAllText(Server.MapPath("Template.htm"))

TemplateHTML = TemplateHTML.Insert(TemplateHTML.IndexOf("<div id=""topContent"">") + "<div id=""topContent"">".Length, _
                                   html.ToString)

doc.LoadHtml(TemplateHTML)

Ответы

Ответ 1

Это происходит потому, что Html Agility Pack обрабатывает BR особым образом. Он по-прежнему поддерживает старый (но существующий в Интернете сегодня) синтаксис HTML 3.2, где BR может быть объявлен без закрывающего тега вообще (браузеры также по-прежнему обрабатывают его изящно, кстати...).

Чтобы изменить это поведение по умолчанию, вам необходимо изменить свойство HtmlNode.ElementFlags, например:

Dim doc As New HtmlDocument()
HtmlNode.ElementsFlags("br") = HtmlElementFlag.Empty
doc.LoadHtml("<test>before<br/>after</test>")
doc.OptionWriteEmptyNodes = True   
doc.Save(Console.Out)

который отобразит:

<test>before<br />after</test>

Ответ 2

В соответствии с @Simon Mourier, следующий код С# работает в версии 1.4

var doc = new HtmlDocument();
HtmlNode.ElementsFlags["br"] = HtmlElementFlag.Empty;
doc.OptionWriteEmptyNodes = true;
doc.LoadHtml("Lorem ipsum dolor sit<br/>Lorem ipsum dolor sit");

var postParsed = doc.DocumentNode.WriteTo();

имеет следующее строковое значение для postParsed

"Lorem ipsum dolor sit<br />Lorem ipsum dolor sit"

Ответ 3

Кажется, это стандартная настройка в Html Agility Pack. По умолчанию он не соответствует XHTML, и многие теги не закрыты.

Есть два способа сделать это. На уровне документа вы можете сделать следующее, которое включит ВСЕ закрывающие теги. (Это мой предпочтительный метод).

HtmlDocument doc = new HtmlDocument();
doc.OptionWriteEmptyNodes = true;
doc.LoadHtml(content);

Однако это может быть нежелательно. Существует еще один способ сделать это на уровне node.

if (HtmlNode.ElementsFlags.ContainsKey("img"))
{
    HtmlNode.ElementsFlags["img"] = HtmlElementFlag.Closed;
}
else
{
    HtmlNode.ElementsFlags.Add("img", HtmlElementFlag.Closed);
}

Ответ 4

Я столкнулся с такой же проблемой, и решил ее вручную путем повторного разбора HTML-фрагмента с использованием нового объекта HtmlDocument с правильными настройками.

Проблема в том, что в HtmlDocument есть все те хорошие настройки, которые позволяют закрыть теги и т.д., но когда вы выбираете node или выполняете некоторые другие действия с узлами и используете их OuterHtml или InnerHtml некоторые из этих закрывающих тегов теряются (вероятно, потому, что эти свойства не используют те же настройки, что и сам документ, или, возможно, есть другая причина). Поэтому, когда вы получите эту неправильную строку html из InnerHtml или OuterHtml, вы можете просто повторно проанализировать ее с помощью HtmlDocument и использовать document.DocumentElement.InnerHtml для получения правильной строки HTML.