OptionWriteEmptyNodes rompe la declaración XML usando HtmlAgilityPack

c# end-tag html-agility-pack non-well-formed xml-declaration

Pregunta

Aquí está el código super simple que tengo:

HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.OptionWriteEmptyNodes = true;
htmlDoc.Load("sourcefilepath");
htmlDoc.Save("destfilepath", Encoding.UTF8);

Entrada:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
    <link rel="stylesheet" href="main.css" type="text/css"/>
  </head>
  <body>lots of text here, obviously not relevant to this problem</body>
</html>

Salida:

<?xml version="1.0" encoding="UTF-8" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
    <link rel="stylesheet" href="main.css" type="text/css" />
  </head>
  <body>lots of text here, obviously not relevant to this problem</body>
</html>

Puede ver que en la primera línea hay un error: /> en lugar de?> Esto sucede si configuro OptionWriteEmptyNodes en valor verdadero. Se ha establecido en verdadero, porque de lo contrario las etiquetas meta / enlace (y algunas otras en el cuerpo del documento) no se cerrarán.

¿Alguien sabe como resolver esto?

Respuesta aceptada

Parece un error. Debe informarlo a http://htmlagilitypack.codeplex.com .

Aún así, puedes solucionar ese error así:

HtmlNode.ElementsFlags.Remove("meta");
HtmlNode.ElementsFlags.Remove("link");
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.Load("sourcefilepath");
htmlDoc.Save("destfilepath", Encoding.UTF8);

Simplemente elimine los indicadores de las etiquetas meta y link que OptionWriteEmptyNodes al Paquete de Agilidad Html que no los cierre automáticamente, y no establezca OptionWriteEmptyNodes en true .

Producirá esto (note que esto es ligeramente diferente):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"></meta>
    <link rel="stylesheet" href="main.css" type="text/css"></link>
  </head>
  <body>lots of text here, obviously not relevant to this problem</body>
</html>

Respuesta popular

Logró hacer otra forma de solucionar este problema. Esto funciona un poco mejor en mi caso que el anterior. Básicamente, estamos reemplazando el primer elemento secundario de DocumentNode, que es la declaración xml (tenga en cuenta que la entrada debe contener la declaración xml, en mi caso es del 100%)

HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.OptionWriteEmptyNodes = true;
htmlDoc.Load("sourcepath");

var newNodeStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
var newNode = HtmlNode.CreateNode(newNodeStr);

htmlDoc.DocumentNode.ReplaceChild(newNode, htmlDoc.DocumentNode.FirstChild);


htmlDoc.Save("destpath", Encoding.UTF8);

Tenga en cuenta que la solución alternativa de Simon también funciona, así que tome la que mejor se adapte a su situación.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué