OptionWriteEmptyNodes使用HtmlAgilityPack破坏XML声明
本文关键字:XML 声明 破坏 HtmlAgilityPack 使用 OptionWriteEmptyNodes | 更新日期: 2023-09-27 18:37:22
这是我拥有的超级简单的代码:
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,因为否则元/链接标签(以及文档正文中的其他一些标签)将不会关闭。
有人知道如何解决这个问题吗?
似乎是一个错误。您应该向 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);
请注意,Simon 的解决方法也有效,因此请选择更适合您的方案的解决方法。
我的页面中也有<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);
}