HTML敏捷包(C#)malforms我的代码

问题描述:

我目前在c#中编写一个桌面应用程序,它也必须处理XHTML文档操作。为此,我使用的是Html Agility Pack,目前看起来没问题。仔细检查Html Agility Pack的输出后,我发现代码没有正确的形成xhtml。HTML敏捷包(C#)malforms我的代码

它消除自闭标签(斜线),并覆盖其他专有代码元素...

如。 输入HTML代码

<input autocapitalize="off" id="username" name="username" placeholder="Benutzername" type="text" value="$(username)" /> 

如。 输出HTML代码

<input autocapitalize="off" id="username" name="username" placeholder="Benutzername" type="text" value="$(username)"> 

(除去最后的斜线...)

另一个例子是专有的代码元素(的MikroTik热点的设备):

例如输入HTML代码

<form action="$(link-login-only)" method="post" name="login" $(if chap-id) onSubmit="return doLogin()"$(endif)> 

The $(if chap-id)$(endif)$(link-login-only)部分是从Mikrotik器件解释的自定义代码片段。

例如。 输出HTML代码后的Html敏捷包(它转变为unuseable代码)

<form action="$(link-login-only)" method="post" name="login" $(if="" chap-id)="" onsubmit="return doLogin()" $(endif)=""> 

有别人的想法如何“指导”的Html敏捷包输出以及形成的XHTML,而忽略“定制代码”片段(这可能是通过正则表达式)?

在此先感谢! :-)

+0

为什么不使用XML解析器,而不是HAP(这是一个HTML,而不是XHTML/XML解析器)?从codplex的项目页面:“虽然您可以使用该工具实际生成XML,但也没有遵守XHTML或XML。” – Oded 2013-05-06 18:31:46

+0

你有没有试过'htmlDocument.Save(XmlWriter);' – I4V 2013-05-06 18:33:23

+0

@ I4V我用''htmlDocument.Save()'' - 方法 – thedom 2013-05-06 18:49:19

在您的第一个示例中,HTML Agility Pack实际上正在修复您的标记。输入元素是void element。由于里面没有上下文,因此不需要结束标记。

HTML Agility Pack是用于解析有效的HTML标记,而不是嵌入自定义代码的标记。在第一个示例中,自定义标记位于引号内,因此不是问题。在第二个例子中,变量在引号之外。

HTML Agility Pack尝试将它们解析为元素的常规(但格式错误)属性。没有办法解决这个问题。如果您需要支持标记中的自定义代码,则必须找到解析标记的另一种方法。

+0

任何想法如何实现?只要有任何方法可以让我的“自定义标签”保持不变,我就可以与“修复”标记一起生活......它不一定非得与HTML敏捷包一起使用。 – thedom 2013-05-06 18:47:52

+0

@Justin Niessner:“由于里面没有上下文,所以不需要结束标记。”:不正确。这取决于输出格式是XHTML/XML还是HTML/SGML。在XHTML/XML的情况下需要它。但问题在于OP没有定义输出格式,因此HtmlAgilityPack使用了默认的(SGML)。 – 2017-09-28 14:19:48

+0

@Justin Niessner:斯特凡·斯泰格所说的,加上:只是一个元素(''div',说)没有实际的内容,不*意味着可以省略结束元素标签。在SGML中,只有那些被声明为具有'EMPTY'内容的元素(忽略'#CONREF'属性和WebSGML/XML)*必须没有末尾元素标签,例如HTML链接''hr','br' ,'img'等元素。但是,例如。 'script'元素,即使与'href'属性一起使用,并且没有文字脚本子内容,*必须*有一个结束元素标记。看到http://sgmljs.net/docs/w3c-html51-dtd.html我的HTML 5.1 DTD参考 – imhotap 2017-09-28 16:45:33

另一种方法是CsQuery,至少对于你在这里得到的简单情况,只会将你的预处理器标签仅仅视为无价值的属性。也就是说,HAP似乎将没有值的任何属性someattribute转换为someattribute=""。 CsQuery不会这样做。

然而,@Justin Niessner关于您的标记的观察结果对于任何不是专门设计用于解析您在其中的模板代码的解析器都是正确的。仅仅因为这个例子通过CsQuery实现它并不能保证其他一些格式不会导致某些不是有效的属性名称,或者如果无效,至少可以被HTML5解析器接受。

如果您需要处理的东西作为HTML,然后再去做模板后。如果你需要在之前操作模板引擎,那么你在catch 22中,因为它还不是HTML。或者,您也可以使用为其关键字使用有效HTML标记的模板系统(例如:Knockout)。

Necromancing。
问题1是因为你可能没有指定OptionOutputAsXml = true,意味着HtmlAgilityPack输出HTML而不是XHTML。

其实,这样做是相当聪明的,因为它减少了文件大小。
如果您需要XHTML,您需要特别指示HtmlAgilityPack输出XHTML(XML),而不是HTML(SGML)。

SGML允许没有结束标记(/>)标签,而XML没有。
为了解决这个问题:

public static void BeautifyHtml() 
{ 
    string input = "<html><body><p>This is some test test<br ><ul><li>item 1<li>item2<</ul></body>"; 

    HtmlAgilityPack.HtmlDocument test = new HtmlAgilityPack.HtmlDocument(); 
    test.LoadHtml(input); 
    test.OptionOutputAsXml = true; 
    test.OptionCheckSyntax = true; 
    test.OptionFixNestedTags = true; 


    System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
    using (System.IO.TextWriter stringWriter = new System.IO.StringWriter(sb)) 
    { 
     test.Save(stringWriter); 
    } 

    string beautified = sb.ToString(); 
    System.Console.WriteLine(beautified); 
}