C# HTMl agility pack解析和返回XElement时出错

C# HTMl agility pack解析和返回XElement时出错,c#,.net-3.5,html-parsing,html-agility-pack,C#,.net 3.5,Html Parsing,Html Agility Pack,我可以解析文档并生成输出,但是由于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标记的原因,无法将输出解析为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>";
var-input=“不知为什么出于某种原因,它是空的!

我已经实现了自动保存功能,但它在100秒后真的能工作吗?
自动保存???我们正在讨论…



我的代码:

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");

}
publicstaticxelement CleanupHtml(字符串输入)
{  
HtmlAgilityPack.HtmlDocument htmlDoc=新的HtmlAgilityPack.HtmlDocument();
htmlDoc.OptionOutputAsXml=true;
//htmlDoc.OptionWriteEmptyNodes=true;
//htmlDoc.OptionAutoCloseOnEnd=true;
htmlDoc.OptionFixNestedTags=true;
htmlDoc.LoadHtml(输入);
//ParseErrors是包含Load语句中任何错误的ArrayList
if(htmlDoc.ParseErrors!=null&&htmlDoc.ParseErrors.Count()>0)
{
}
其他的
{
if(htmlDoc.DocumentNode!=null)
{
var ndoc=new HtmlDocument();//HTML文档实例
HtmlNode p=ndoc.CreateElement(“主体”);
p、 InnerHtml=htmlDoc.DocumentNode.InnerHtml;
var result=p.OuterHtml.Replace(“
”,“
”); 结果=结果。替换(“
”,“
”); 结果=结果。替换(“
”,“
”); 返回XElement.Parse(result,LoadOptions.PreserveWhitespace); } } 返回新的XElement(“正文”); }
我的输出:

<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>

不知道为什么是空的,因为一些奇怪的原因,查皮!


我已经实现了自动保存功能,但它在100秒后真的有效吗?

自动保存??

我们正在谈论

****


粗体p标记是输出不正确的标记。。。有办法解决这个问题吗?我的代码有问题吗?

如果您检查
选项的文档注释,您将看到以下内容:

//     Defines if LI, TR, TH, TD tags must be partially fixed when nesting errors
//     are detected. Default is false.

因此,我认为这对未关闭的HTML
p
标记没有帮助。根据一个古老的SO问题,这可能适用于此目的。

您试图做的基本上是将Html输入转换为Xml输出

当您使用
选项outputasxml
选项时,Html Agility Pack可以做到这一点,但是在这种情况下,您不应该使用InnerHtml属性,而是让Html Agility Pack使用HtmlDocument的
Save
方法之一为您做基础工作

以下是将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函数(选择节点、添加、删除等)。

谢谢您提供的信息。。。我输入的问题是我有一个有效的

标记,但没有正确处理,它们只是空元素!

变为这是有效的,很奇怪为什么我必须保存以获得正确的输出,无论如何-我将如何处理nbsp;是否包含在输入中?您会建议我使用anti.xss库吗?+1我甚至不知道
OptionOutputAsXml
(及其用例)在转换过程中似乎并不特别可靠,例如,我得到以下错误:6XmlException“”,十六进制值0x03,是无效字符。第2081行,位置822。行号2081行位置822如果是新问题,请发布新问题。