65.9K
CodeProject 正在变化。 阅读更多。
Home

EfTidyNet:Tidy 库的 .NET 包装器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (11投票s)

2008 年 3 月 5 日

GPL3

8分钟阅读

viewsIcon

123710

downloadIcon

1650

用于解析 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

EfTidy 版本 1.0.1.3
  • Source zip 包含
    • TidyLib (原始 Tidy 库)2009 年 3 月发布源代码
    • EfTidyNet 源代码,支持多语言
  • Project zip 包含
    • 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
© . All rights reserved.