[英]OptionWriteEmptyNodes break XML declaration using HtmlAgilityPack
這是我有的超級簡單代碼:
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,因為否則將不會關閉元/鏈接標記(以及文檔正文中的其他標記)。
有誰知道如何解決這個問題?
好像是一個bug。 您應該將其報告給http://htmlagilitypack.codeplex.com 。
不過,你可以像這樣解決這個bug:
HtmlNode.ElementsFlags.Remove("meta");
HtmlNode.ElementsFlags.Remove("link");
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.Load("sourcefilepath");
htmlDoc.Save("destfilepath", Encoding.UTF8);
只需刪除指示Html Agility Pack不會自動關閉它們的meta
和link
標記中的標記,並且不要將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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.