1

我目前正在用 c# 编写一个桌面应用程序,它还必须处理 XHTML 文档操作。为此,我正在使用Html Agility Pack,到目前为止似乎还可以。在仔细检查了 Html Agility Pack 的输出后,我发现代码不再是格式良好的 xhtml。

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

例如。输入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)>

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

例如。在 Html Agility Pack 之后输出 html 代码(将其转换为不可用的代码)

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

有人知道如何“指导” Html Agility Pack 输出格式良好的 XHTML 并忽略“自定义代码”片段(这可能是通过正则表达式)吗?

提前致谢!:-)

4

3 回答 3

3

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

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

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

于 2013-05-06T18:36:14.697 回答
2

死灵术。
问题 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);
}
于 2017-09-28T14:03:41.917 回答
0

另一种选择是CsQuery,至少对于您在这里遇到的简单情况,它会留下您的预处理器标签,本质上只是将它们视为无价值的属性。也就是说,HAP 似乎将任何someattribute没有值的属性转换为someattribute="". CsQuery 不会这样做。

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

如果您需要将某些内容作为 HTML 进行操作,请在模板化之后进行。如果您需要在模板引擎处理它之前对其进行操作,那么您就遇到了第 22 个问题,因为它还不是 HTML。或者,您可以使用一个模板系统,该系统使用有效的 HTML 标记作为其关键字(例如:Knockout)。

于 2013-05-06T19:09:27.513 回答