0

这是我拥有的超级简单的代码:

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 值,则会发生这种情况。它已设置为 true,否则元/链接标签(以及文档正文中的其他一些标签)将不会被关闭。

有谁知道如何解决这个问题?

4

3 回答 3

1

似乎是一个错误。您应该将其报告给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 不要自动关闭它们的标志,并且不要设置OptionWriteEmptyNodestrue.

它将产生这个(注意这略有不同):

<?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>
于 2012-06-15T09:56:26.563 回答
1

设法做另一种解决这个问题的方法。在我的情况下,这比上面的情况要好一些。基本上我们正在替换 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);

请注意,Simon 的解决方法也有效,因此请选择更适合您的场景的方法。

于 2012-06-15T12:39:18.710 回答
0

我的页面中也有<br/>标签,并htmlDoc.OptionWriteEmptyNodes = true;通过将它们替换为<br>. 我找到了一种类似于 Alex 的答案的方法,但更通用一些,以便保留大部分原始值,并且不依赖于页面中始终存在 xml 标记:

HtmlDocument doc= new HtmlDocument();
doc.OptionWriteEmptyNodes = true;
doc.Load("pathToFile");
if (doc.DocumentNode.FirstChild.OriginalName.Equals("?xml"))
{
    var fixedOuterHtml = doc.DocumentNode.FirstChild.OuterHtml.Replace('/', '?');
    var newNode = HtmlNode.CreateNode(fixedOuterHtml);
    doc.DocumentNode.ReplaceChild(newNode, doc.DocumentNode.FirstChild);
}
于 2017-07-14T23:11:41.943 回答