OptionWriteEmptyNodes нарушает объявление XML с помощью HtmlAgilityPack

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

Вопрос

Вот супер простой код, который у меня есть:

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

Входные данные:

<?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>

Вывод:

<?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>

Вы можете видеть, что в первой строке есть ошибка: /> вместо?> Это происходит, если я устанавливаю значение OptionWriteEmptyNodes истинному значению. Он был установлен в true, потому что в противном случае метки мета / ссылки (и некоторые другие в документе) не будут закрыты.

Кто-нибудь знает, как это решить?

Принятый ответ

Похоже на ошибку. Вы должны сообщить об этом http://htmlagilitypack.codeplex.com .

Тем не менее, вы можете обойти эту ошибку следующим образом:

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

Просто удалите флажки из тегов meta & link которые инструктируют Html Agility Pack не закрывать их автоматически, и не устанавливайте параметр OptionWriteEmptyNodes в true .

Это произведет это (обратите внимание, что это немного отличается):

<?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>

Популярные ответы

Удалось сделать другой способ обхода этой проблемы. В моем случае это немного лучше, чем выше. В основном мы заменяем первый ребенок DocumentNode, который является объявлением xml (обратите внимание, что вход должен содержать объявление xml, в моем случае это 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);

Обратите внимание, что обходной путь Саймона тоже работает, поэтому возьмите тот, который лучше подходит для вашего сценария.



Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему