EfTidyNet:Tidy 库的 .NET 包装器
用于解析 HTML 的免费组件,EfTidyCom 的 .NET 版本
引言
在深入细节之前,我想让您了解 EfTidy
实际上是什么。 EfTidy
是 Tidy
库的一个包装器组件,如果您不知道 Tidy
是什么,这里有一个简短的描述
"
TidyLib
是一个用于整理 HTML 的开源实用程序。Tidy
由一个 HTML 解析器和一个 HTML 美化打印程序组成。解析器会尽力纠正常见的标记错误。它还会就如何提高页面的可访问性(对残疾人士而言)提供建议,并可用于将 HTML 内容转换为 XHTML 格式的 XML。Tidy
是 W3C 开源项目,免费提供。它已在大量平台上成功编译,并被集成到许多 HTML 编辑工具中。"- Dave Raggett 先生
这是 EfTidyCom
组件的 .NET 版本(也曾在 The Code Project 上发布)。在继续之前,本库谨献给我最近(2008 年 1 月 29 日)去世的母亲已故 Saroj Gupta 女士,我只想说妈妈!我爱您。
我收到了很多要求提供 EfTidyCom
库的 .NET 版本。COM 正在失去焦点,而 .NET 似乎是未来。本库是用 VC++.NET 编写的(通过混合托管和非托管代码)。请在本篇文章中查找引用和测试用例。感谢您,并为我的母亲祈祷,愿她在任何地方都过得快乐。
这也是 EfTidyCom
的一个更新版本。一些功能(Node
和 Attribute
类)已被移除,因为我认为它们用处不大!
库引用
EfTidy
包含两个类
TidyNetOpt
[在EfTidyNet
命名空间下]TidyNet
[在EfTidyNet::EfTidyOpt
命名空间下]
EfTidy
还包含四个枚举
ECharEncodingType
EOutputType
EIndentScheme
EDoctypeModes
现在,我们逐一介绍每个接口。
1. TidyNet
首先,让我们检查此 interface
中存在的每个方法或属性,以及它们执行的功能
属性/方法名称 | 参数 | Get/Put | 描述 |
TidyFiletoMem |
const String^ SFileName , String^ % SResult |
不适用 | 将输出写入内存。 |
TidyFileToFile |
const String^ SsourceFileName , const String^ SDestFile |
不适用 | 将输出写入文件。 |
TidyMemToMem |
String^ SsourceData , String^ % SResult |
不适用 | 将输出写入内存。 |
TidyMemtoFile |
String^ SBuffer , String^ SDestFile |
不适用 | 将输入作为缓冲区,输出到文件。 |
TotalWarnings |
long %pVal |
Get |
返回上述四项操作的总警告数。 |
TotalErrors |
long %pVal |
Get |
返回上述四项操作的总错误数。 |
ErrorWarning |
void |
String^ |
返回包含人类可读错误/警告的缓冲区。 |
选项 |
void |
EfTidyOpt:: TidyNetOpt^ |
设置 Tidy 库的 Option 。 |
2. TidyNetOpt
以下是 ItidyOption interface
的属性和方法的列表
属性/方法名称 | 参数 | Get/Put | 描述 |
LoadConfigFile |
String^ |
不适用 | 从配置文件加载选项设置。 |
ResetToDefaultValue |
Void |
不适用 | 将选项重置为默认设置。 |
Doctype |
String^ |
两者 | Tidy 生成的 Doctype 声明。 |
TidyMark |
BOOL |
两者 | 用于 meta 元素,指示已整理的文档。 |
HideEndTag |
BOOL |
两者 | 隐藏可选的结束标签。 |
EncloseText |
BOOL |
两者 | 如果为 yes,则 body 中的文本将被 <p> 包裹。 |
EncloseBlockText |
BOOL |
两者 | 如果为 yes,则块中的文本将被 <p> 包裹 |
LogicalEmphasis |
BOOL |
两者 | 将 i 替换为 em ,将 b 替换为 strong 。 |
DefaultAltText |
String^ |
两者 | alt 属性的默认文本。 |
Clean |
BOOL |
两者 | 用样式规则替换表现性的杂乱内容。 |
DropFontTags |
BOOL |
两者 | 丢弃表现性标签。 |
DropEmptyParas |
BOOL |
两者 | 丢弃空的 p 元素。 |
Word2000 |
BOOL |
两者 | 对 Word2000 进行严苛的清理。 |
FixBadComment |
BOOL |
两者 | 修复带有相邻连字符的注释。 |
FixBackslash |
BOOL |
两者 | 通过将 \ 替换为 / 来修复 URL。 |
NewEmptyTags |
String^ |
两者 | 声明的空标签。 |
NewInlineTags |
String^ |
两者 | 声明的内联标签。 |
NewBlockLevelTags |
String^ |
两者 | 声明的块级标签。 |
NewPreTags |
String^ |
两者 | 声明的 pre 标签。 |
OutputType |
EOutputType |
两者 | 您可以从这里设置输出类型,例如,您可以将输出获取为 XML、XHTML 或纯 HTML。 |
InputAsXML |
BOOL |
两者 | 将输入视为 XML。 |
ADDXmlDecl |
BOOL |
两者 | 为 XML 文档添加 >?xml ?<。 |
AddXmlSpace |
BOOL |
两者 | 如果设置为 yes,则按需添加 XML:space 属性。 |
Bare |
BOOL |
两者 | 生成纯 HTML。 |
AssumeXmlProcins |
BOOL |
两者 | 如果设置为 yes,则 PI 必须以 ?> 结尾。 |
CharEncoding |
ECharEncodingType |
两者 | 设置/获取输入/输出字符编码。 |
InCharEncoding |
ECharEncodingType |
两者 | 输入字符编码(如果不同)。 |
OutCharEncoding |
ECharEncodingType |
两者 | 输出字符编码(如果不同)。 |
NumericsEntities |
BOOL |
两者 | 对符号使用数字实体。 |
QuoteMarks |
BOOL |
两者 | 将 " 符号输出为 " 。 |
QuoteNBSP |
BOOL |
两者 | 将不间断空格也输出为实体。 |
QuoteAmpersand |
BOOL |
两者 | 将裸露的 & 输出为 & 。 |
OutputTagInUpperCase |
BOOL |
两者 | 以大写而不是小写输出标签。 |
OutputAttrInUpperCase |
BOOL |
两者 | 以大写而不是小写输出属性。 |
WrapScriptlets |
BOOL |
两者 | 在 JavaScript 字符串字面量中换行。 |
WrapAttVals |
BOOL |
两者 | 在属性值中换行。 |
WrapSection |
BOOL |
两者 | 在 section 标签中换行。 |
WrapAsp |
BOOL |
两者 | 在 ASP 伪元素中换行。 |
WrapJste |
BOOL |
两者 | 在 JSTE 伪元素中换行。 |
WrapPhp |
BOOL |
两者 | 在 PHP 伪元素中换行。 |
Indent |
EIndentScheme |
两者 | 缩进适当标签的内容。 |
IndentSpace |
long |
两者 | 缩进 n 个空格。 |
WrapLen |
long |
两者 | 设置输出的换行边距。 |
TabSize |
long |
两者 | 将制表符扩展为 n 个空格。 |
IndentAttributes |
long |
两者 | 在每个属性之前添加换行符 + 缩进。 |
BreakBeforeBR |
BOOL |
两者 | 在之前或之后输出换行符。 |
LiteralAttribs |
BOOL |
两者 | 如果为 true ,属性可以使用换行符。 |
MarkUp |
BOOL |
两者 | |
ShowWarnings |
BOOL |
两者 | 开/关 |
Quiet |
BOOL |
两者 | 无“正在解析 X”,猜测的 DTD 或摘要。 |
KeepTime |
BOOL |
两者 | 如果为 yes,则保留最后修改时间。 |
ErrorFile |
String^ |
两者 | 写入错误的文件名。 |
GnuEmacs |
BOOL |
两者 | 如果为 true ,则为 GNU Emacs 格式化错误输出。 |
FixUrl |
BOOL |
两者 | 在必要时应用 URI 编码。 |
BodyOnly |
BOOL |
两者 | 仅输出 BODY 内容。 |
HideComments |
BOOL |
两者 | 隐藏输出中的所有(实际)注释。 |
DoctypeMode |
EDoctypeModes |
两者 | 设置输出的 doctype 模式。 |
Using the Code
我使用了Test.htm(包含在项目文件中)来测试 EfTidyNet
的响应。Test.htm 的内容如下
<html>
<head><title>tidy Library</title></head>
<body>
<blockquote>
<p> </p> --(1)
<p><fontsize="5"color=
"#FF00FF">TidyLibrary</font></p>
</blockquote>
<P><p><fontsize="5"color="#FF00FF"></font></p>
<table border="1" cellpadding="0" cellspacing="0"
style="border-collapse: collapse"
bordercolor="#111111" width="100%" id="AutoNumber1">
<tr>
<td width="50%" style="border-left-style: solid;
border-left-width: 1; border-right-style: none;
border-right-width: medium; border-top-style: solid;
border-top-width: 1; border-bottom-style:
none; border-bottom-width: medium"> --(2)
</td>
<td width="50%" style="border-left-style: none;
border-left-width: medium; border-right-style:solid;
border-right-width: 1; border-top-style: solid;
border-top-width: 1;border-bottom-style: none;
border-bottom-width: medium">
</td>
</tr>
</table>
<b>Tidy --- (3)
</h1> <tidy> ---(4)
</body>
</html>
在 test.htm 中,我添加了以下错误
- 一个假的
<Tidy>
标签,位于 (4) - 缺少
<h1>
标签,位于 (4) - 空的段落
<p>
标签 (1) - 未关闭的
<b>
标签,位于 (3)
测试用例 # 1 使用 TidyNet
首先,创建我们组件的一个对象。以下是如何实现此目标的列表
TidyNet objTidyNet = new TidyNet();
现在,使用此对象清理 test.htm 文件。代码列表如下
private void button1_Click(object sender, EventArgs e)
{
int iTotalWarn = 0,iTotalErrs = 0;
String SReturnData ="";
String SError = "";
TidyNet objTidyNet = new TidyNet();
objTidyNet.TidyFiletoMem("C:\\MyProjects\\Test\\hello.htm",
ref SReturnData);
objTidyNet.TotalWarnings(ref iTotalWarn);
SError = objTidyNet.ErrorWarning();
objTidyNet.TotalErrors(ref iTotalErrs);
}
以下是 Tidy
生成的输出结果,显示 test1.htm(由 EfTidyNet
创建)的内容
<html>
<head>
<meta name="generator"
content="HTML Tidy for Windows (vers 1st September 2004),
see www.w3.org">
<title>tidy Library</title>
</head>
<body>
<blockquote>
<p> </p>
<p><font size="5" color="#FF00FF">Tidy Library</font>
</p>
</blockquote>
<p><font size="5" color= "#FF00FF"> </font></p>
<table border="1" cellpadding="0" cellspacing="0"
style= "border-collapse: collapse" bordercolor="#111111"
width="100%" id= "AutoNumber1">
<tr>
<td width="50%" style= "border-left-style: solid;
border-left-width: 1; border-right-style: none;
border-right-width: medium; border-top-style: solid;
border-top-width: 1; border-bottom-style: none;
border-bottom-width: medium">
</td>
<td width="50%"
style= "border-left-style: none;border-left-width: medium;
border-right-style: solid; border-right-width: 1;
border-top-style: solid; border-top-width: 1;
border-bottom-style: none;border-bottom-width: medium">
</td>
</tr>
</table>
<b>Tidy</b> --(1)
</body>
</html>
如果您查看上面的已清理的 HTML 页面,您会发现假的 <tidy>
标签和 </h1>
已在 (1) 附近被移除,并且 </b>
已在 (1) 处的 Tidy
之后添加。
以下是 EfTidyNet
生成的错误/警告摘要,显示了它执行的每个操作的详细信息
line 1 column 1 - Warning: missing <!DOCTYPE> declaration
line 22 column 10 - Warning: discarding unexpected </h1>
line 23 column 1 - Error: <tidy> is not recognized!
line 23 column 1 - Warning: discarding unexpected <tidy>
line 15 column 1 - Warning: <table> proprietary attribute
"bordercolor"
line 15 column 1 - Warning: <table> lacks "summary" attribute
Info: Document content looks like HTML Proprietary
5 warnings, 1 error were found!
测试用例 # 2 使用 TidyNet 和 TidyNetOpt
现在,对 Test.htm 应用一些选项以获得自定义输出。因此,我使用以下选项
Clean =TRUE
(为样式创建单独的类)DoctypeMode = DoctypeUser
(启用显示string
)Doctype = "Ef Tidy library"
(显示string
)OutputType = XhtmlOut
(输出类型)NewInlineTags = "tidy"
(使我们的假<tidy>
标签合法)
以下是实现上述目标的 C# 代码列表
private void TestCase2_Click(object sender, EventArgs e)
{
int iTotalWarn = 0, iTotalErrs = 0;
String SReturnData = "";
String SError = "";
TidyNet objTidyNet = new TidyNet();
objTidyNet.Option.Clean(true);
objTidyNet.Option.NewInlineTags("tidy");
objTidyNet.Option.OutputType(EfTidyNet.EfTidyOpt.EOutputType.XhtmlOut);
objTidyNet.Option.DoctypeMode(EfTidyNet.EfTidyOpt.EDoctypeModes.DoctypeUser);
objTidyNet.Option.Doctype("Ef Tidy Library");
objTidyNet.TidyFiletoMem("C:\\MyProjects\\Test\\hello.htm", ref SReturnData);
objTidyNet.TotalWarnings(ref iTotalWarn);
SError = objTidyNet.ErrorWarning();
objTidyNet.TotalErrors(ref iTotalErrs);
}
以下是 Tidy
生成的输出结果,显示 test1.htm(由 EfTidyNet
创建)在应用我们的选项后包含的内容
<!DOCTYPE html PUBLIC "Ef Tidy library" ""> --(1)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator"
content="HTML Tidy for Windows (vers 1st September 2004),
see www.w3.org" />
<title>tidy Library</title>
<style type="text/css"> --(2)
/*<![CDATA[*/
table.c4 {border-collapse: collapse}
td.c3 {border-left-style: none;
border-left-width: medium; border-right-style: solid;
border-right-width: 1; border-top-style: solid;
border-top-width: 1;
border-bottom-style: none; border-bottom-width: medium}
td.c2 {border-left-style: solid; border-left-width: 1;
border-right-style: none;
border-right-width: medium; border-top-style: solid;
border-top-width: 1;
border-bottom-style: none; border-bottom-width: medium}
h2.c1 {color: #FF00FF}
/*]]>*/
</style>
</head>
<body>
<blockquote>
<p> </p>
<h2 class="c1">Tidy Library</h2>
</blockquote>
<h2 class="c1">
</h2>
<table border="1" cellpadding="0" cellspacing="0" class="c4"
bordercolor="#111111" width="100%" id="AutoNumber1">
<tr>
<td width="50%" class="c2"> </td> ----(3)
<td width="50%" class="c3"> </td>
</tr>
</table>
<b>Tidy <tidy></tidy></b> ----(4)
</body>
</html>
现在,让我们看看 Tidy
为我们清理了什么
- 在 (1) 中,可以看到我们自定义的
string
"Ef Tidy Library
"。 - 在 (2) 和 (3) 中,样式被清理并为其创建了一个类。
- 在 (4) 中,我们的
<Tidy>
标签合法了,尽管它在实际 HTML 页面中没有任何作用。
以下是所有错误/警告的摘要
line 1 column 1 - Warning: missing <!DOCTYPE> declaration
line 22 column 10- Warning: discarding unexpected </h1>
line 23 column 1 - Warning: <tidy> is not approved by W3C
line 23 column 1 - Warning: missing </tidy> before </body>
line 22 column 2 - Warning: missing </b> before </body>
line 15 column 1 - Warning: <table> proprietary attribute
"bordercolor"
line 15 column 1 - Warning: <table> lacks "summary" attribute
Info: Document content looks like HTML Proprietary
7 warnings, 0 errors were found!
这里,我只给出了 Tidy
库和 EfTidyCom
的一个简要概述。有关 Tidy
库的更多信息,请访问 Tidy
主页。
作者评论
我知道这个组件还有很大的改进空间。我承诺在下一版本/更新中会进行这些改进。如果您遇到任何错误,请告知我,以便我进一步改进代码。
项目中列出的文件
EfTidy 版本 1.0.2.0
- Source zip 包含
TidyLib
(原始 Tidy
库)2009 年 3 月发布源代码
EfTidyNet
源代码,支持多语言- 更新到 Visual Studio 2010 的源代码
- Project zip 包含
EfTidyNet
库的发布版本
- C# 测试项目(含源代码)
- Test.htm
TidyLib
(原始Tidy
库)2009 年 3 月发布源代码EfTidyNet
源代码,支持多语言- 更新到 Visual Studio 2010 的源代码
EfTidyNet
库的发布版本- C# 测试项目(含源代码)
- Test.htm
EfTidy 版本 1.0.1.3
- Source zip 包含
TidyLib
(原始 Tidy
库)2009 年 3 月发布源代码
EfTidyNet
源代码,支持多语言
- Project zip 包含
EfTidyNet
库的发布版本
- C# 测试项目(含源代码)
- Test.htm
TidyLib
(原始Tidy
库)2009 年 3 月发布源代码EfTidyNet
源代码,支持多语言
EfTidyNet
库的发布版本- C# 测试项目(含源代码)
- Test.htm
EfTidy 版本 1.0.1.2(最新)
- Source zip 包含
TidyLib
(原始Tidy
库)2008 年发布源代码EfTidyNet
源代码,支持多语言- 感谢 Wingogo 和 megger83 报告 bug!
- Project zip 包含
EfTidyNet
库的发布版本
EfTidy 版本 1.0.1.1
- Source zip 包含
TidyLib
(原始Tidy
库)2008 年发布源代码EfTidyNet
源代码,支持多语言EfTidyNetx64
版本,由 Spike 提供!
- Project zip 包含
EfTidyNet
库的发布版本- C# 测试项目(含源代码)
- Test.htm
EfTidy 版本 1.0
- Source zip 包含
TidyLib
(原始Tidy
库)源代码EfTidyNet
源代码
- Project zip 包含
EfTidyNet
库的发布版本- C# 测试项目(含源代码)
- Test.htm
特别感谢
- Mr. Saurabh Gupta [Efextra eSolutions Pvt. Ltd. 董事]
- Spike 先生,感谢您创建
EfTidyNet
的 X64 版本 - Tidy SourceForge 组,感谢提供
Tidy
库
更新历史
- 2013 年 9 月 6 日:EfTidyNet 版本 1.0.2.0
- 2009 年 7 月 20 日:EfTidyNet 版本 1.0.1.3
- 2008 年 6 月 23 日:
EfTidyNet
版本 1.0.1.2 - 2008 年 3 月 5 日:
EfTidyNet
版本 1.0.1.1 - 2008 年 2 月 15 日:
EfTidyNet
版本 1.0