asp.net vb.net html-agility-pack

asp.net - El paquete de agilidad HTML elimina la etiqueta de ruptura



vb.net html-agility-pack (4)

Estoy creando un documento HTML usando el paquete de agilidad HTML. Cargo un archivo de plantilla y luego le agrego contenido. Todo esto funciona, pero cuando veo el archivo de salida, eliminé la etiqueta de cierre de mis etiquetas <br/> para parecerme a esta <br> . ¿Qué está causando esto?

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)

Más información:

Estaba eliminando mis etiquetas de imagen de cierre, después de que agregué doc.OptionWriteEmptyNodes = True .

Actualizar

Este es mi código tal como está ahora que elimina la etiqueta de cierre de 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)

Actualización 2

Terminé solo leyendo mi archivo de plantilla como una cadena estándar y luego cargando el html como este

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)


He encontrado el mismo tipo de problema y lo resolví volviendo a analizar manualmente el fragmento HTML utilizando el nuevo objeto HtmlDocument con la configuración correcta.

El problema que veo es que HtmlDocument tiene todas esas configuraciones agradables que te permiten cerrar
etiquetas, etc., pero cuando selecciona un nodo o hace algún otro software de operación con nodos y utiliza su OuterHtml o InnerHtml, algunas de esas etiquetas de cierre se pierden (probablemente porque esas propiedades no usan la misma configuración que el documento en sí, o meybe hay algunas otra razon). Entonces, cuando obtiene esa cadena html incorrecta de InnerHtml o OuterHtml, puede volver a analizarla con HtmlDocument de nuevo y usar document.DocumentElement.InnerHtml para obtener la cadena HTML correcta.


Ocurre porque el Html Agility Pack maneja el BR de una manera especial. Todavía es compatible con la sintaxis HTML 3.2 antigua (pero que existe hoy en día en la web) en la que la BR podría declararse sin ninguna etiqueta de cierre (los navegadores también lo manejan con elegancia, por cierto ...).

Para cambiar este comportamiento predeterminado, necesita modificar la propiedad HtmlNode.ElementFlags , como esto:

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

que mostrará:

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


Parece que esta es una configuración estándar en Html Agility Pack. Por defecto, no cumple con XHTML y muchas etiquetas no están cerradas.

Hay 2 formas de hacer esto. En el nivel de documento, puede hacer lo siguiente que activará TODAS las etiquetas de cierre. (Este es mi método preferido).

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

Sin embargo, esto puede no ser deseable. Hay otra forma de hacerlo a nivel de nodo.

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


Según @Simon Mourier, el siguiente código de C # funciona en la versión 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();

tiene el siguiente valor de cadena para postParsed

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