它實際上按預期工作,但可能不起作用您預期的。無論如何,下面是一段代碼示例(一個控制檯應用程序),演示瞭如何使用該庫實現一些HTML修復。
該庫有一個ParseErrors
集合,您可以使用它來確定在標記解析期間檢測到哪些錯誤。
實際上有兩種類型的問題在這裏:
1)未閉合的元素。這個庫默認是固定的,但P元素上有一個選項可以防止這種情況發生。
2)未開封元素。這個更復雜,因爲它取決於你想如何修復它,你想在哪裏打開標籤?在下面的示例中,我使用了最近的以前的文本兄弟節點來打開該元素。
static void Main(string[] args)
{
// clear the flags on P so unclosed elements in P will be auto closed.
HtmlNode.ElementsFlags.Remove("p");
// load the document
HtmlDocument doc = new HtmlDocument();
doc.Load("yourTestFile.htm");
// build a list of nodes ordered by stream position
NodePositions pos = new NodePositions(doc);
// browse all tags detected as not opened
foreach (HtmlParseError error in doc.ParseErrors.Where(e => e.Code == HtmlParseErrorCode.TagNotOpened))
{
// find the text node just before this error
HtmlTextNode last = pos.Nodes.OfType<HtmlTextNode>().LastOrDefault(n => n.StreamPosition < error.StreamPosition);
if (last != null)
{
// fix the text; reintroduce the broken tag
last.Text = error.SourceText.Replace("/", "") + last.Text + error.SourceText;
}
}
doc.Save(Console.Out);
}
public class NodePositions
{
public NodePositions(HtmlDocument doc)
{
AddNode(doc.DocumentNode);
Nodes.Sort(new NodePositionComparer());
}
private void AddNode(HtmlNode node)
{
Nodes.Add(node);
foreach (HtmlNode child in node.ChildNodes)
{
AddNode(child);
}
}
private class NodePositionComparer : IComparer<HtmlNode>
{
public int Compare(HtmlNode x, HtmlNode y)
{
return x.StreamPosition.CompareTo(y.StreamPosition);
}
}
public List<HtmlNode> Nodes = new List<HtmlNode>();
}
謝謝西蒙,我需要「消化」這:)這是很好的直接聽到作者,你的工作在HAP是非常廣泛的讚賞。 – avo
上有特殊情況嗎? 我只問,因爲我似乎正在收到意想不到的行爲周圍框架沒有被自動關閉。 – twobob
@twobob - 是的,也許,你可以在這裏檢查這個行爲(框架聲明,你可以使用ElementFlags集合刪除它):http://htmlagilitypack.codeplex.com/SourceControl/latest#Trunk/HtmlAgilityPack/HtmlNode.cs –