HTMl 敏捷包错误解析并返回 XElement
Posted
技术标签:
【中文标题】HTMl 敏捷包错误解析并返回 XElement【英文标题】:HTMl agility pack error parsing and returning XElement 【发布时间】:2011-07-17 13:19:31 【问题描述】:我可以解析文档并生成输出,但是由于 p 标记,输出无法解析为 XElement,字符串中的其他所有内容均已正确解析。
我的意见:
var input = "<p> Not sure why is is null for some wierd reason!<br><br>I have implemented the auto save feature, but does it really work after 100s?<br></p> <p> <i>Autosave?? </i> </p> <p>we are talking...</p><p></p><hr><p><br class=\"GENTICS_ephemera\"></p>";
我的代码:
public static XElement Cleanuphtml(string input)
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.OptionOutputAsXml = true;
//htmlDoc.OptionWriteEmptyNodes = true;
//htmlDoc.OptionAutoCloseOnEnd = true;
htmlDoc.OptionFixNestedTags = true;
htmlDoc.LoadHtml(input);
// ParseErrors is an ArrayList containing any errors from the Load statement
if (htmlDoc.ParseErrors != null && htmlDoc.ParseErrors.Count() > 0)
else
if (htmlDoc.DocumentNode != null)
var ndoc = new HtmlDocument(); // HTML doc instance
HtmlNode p = ndoc.CreateElement("body");
p.InnerHtml = htmlDoc.DocumentNode.InnerHtml;
var result = p.OuterHtml.Replace("<br>", "<br/>");
result = result.Replace("<br class=\"special_class\">", "<br/>");
result = result.Replace("<hr>", "<hr/>");
return XElement.Parse(result, LoadOptions.PreserveWhitespace);
return new XElement("body");
我的输出:
<body>
<p> Not sure why is is null for some wierd reason chappy!
<br/>
<br/>I have implemented the auto save feature, but does it really work after 100s?
<br/>
</p>
<p>
<i>Autosave?? </i>
</p>
<p>we are talking...</p>
**<p>**
<hr/>
<p>
<br/>
</p>
</body>
粗体 p 标签是没有正确输出的标签...有没有办法解决这个问题?我的代码有问题吗?
【问题讨论】:
【参考方案1】:您要做的基本上是将 Html 输入转换为 Xml 输出。
当您使用 OptionOutputAsXml
选项时,Html Agility Pack 可以做到这一点,但在这种情况下,您不应该使用 InnerHtml 属性,而是让 Html Agility Pack 为您完成基础工作,使用 HtmlDocument 的 @ 之一987654322@ 方法。
这是一个将 Html 文本转换为 XElement 实例的通用函数:
public static XElement HtmlToXElement(string html)
if (html == null)
throw new ArgumentNullException("html");
HtmlDocument doc = new HtmlDocument();
doc.OptionOutputAsXml = true;
doc.LoadHtml(html);
using (StringWriter writer = new StringWriter())
doc.Save(writer);
using (StringReader reader = new StringReader(writer.ToString()))
return XElement.Load(reader);
如您所见,您不必自己做很多工作!请注意,由于您的原始输入文本没有根元素,因此 Html Agility Pack 会自动添加一个封闭的 SPAN
以确保输出是有效的 Xml。
在你的情况下,你想额外处理一些标签,所以,这里是如何处理你的例子:
public static XElement CleanupHtml(string input)
if (input == null)
throw new ArgumentNullException("input");
HtmlDocument doc = new HtmlDocument();
doc.OptionOutputAsXml = true;
doc.LoadHtml(input);
// extra processing, remove some attributes using DOM
HtmlNodeCollection coll = doc.DocumentNode.SelectNodes("//br[@class='special_class']");
if (coll != null)
foreach (HtmlNode node in coll)
node.Attributes.Remove("class");
using (StringWriter writer = new StringWriter())
doc.Save(writer);
using (StringReader reader = new StringReader(writer.ToString()))
return XElement.Load(reader);
如您所见,您不应使用原始字符串函数,而应使用 Html Agility Pack DOM 函数(SelectNodes、Add、Remove 等...)。
【讨论】:
这行得通,很奇怪为什么我必须保存才能获得正确的输出,无论如何 - 我将如何处理 nbsp;如果它包含在输入中?你会推荐我使用 anti.xss 库吗? +1 我什至不知道OptionOutputAsXml
(及其用例)
HtmlAgilityPack 的转换似乎不是特别可靠,例如我收到此错误:6XmlException '',十六进制值 0x03,是无效字符。第 2081 行,位置 822。 LineNumber 2081 LinePosition 822
如果是新问题,请发布新问题。【参考方案2】:
如果您查看 OptionFixNestedTags
的文档 cmets,您将看到以下内容:
// Defines if LI, TR, TH, TD tags must be partially fixed when nesting errors
// are detected. Default is false.
所以我认为这不会帮助您处理未封闭的 HTML p
标签。根据一个旧的 SO 问题 C# library to clean up html 尽管 HTML Tidy 可能适用于此目的。
【讨论】:
感谢您的信息...我输入的问题是我有一个有效的 标签,但它没有被正确处理,它们只是空元素! 变成以上是关于HTMl 敏捷包错误解析并返回 XElement的主要内容,如果未能解决你的问题,请参考以下文章