簡體   English   中英

OptionWriteEmptyNodes使用HtmlAgilityPack中斷XML聲明

[英]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不會自動關閉它們的metalink標記中的標記,並且不要將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM