文章源自:http://www.ibm.com/developerworks/cn/xml/x-tiptagsoup.html
将格式不好的 HTML 转换成有效的 XHTML
XHTML 对于解析和屏幕擦除是一种足够友好的格式,但是 Web 仍然有很多杂乱的 HTML。在本技巧中,Uche Ogbuji 演示了使用 TagSoup 来将任何杂乱的 HTML 转换成整洁的 XHTML。
XHTML 的一个重要目标是为开发人员提供一种清洁且易于解析的 Web 格式,这是必须进行屏幕擦除 的人所喜欢的。问题是 Web 大部分仍然是用遗留的 HTML 填充的,它们甚至不与更加宽容的 SGML 标准兼容。结构不好的 HTML 被嘲讽为 tag soup,而这也是 John Cowan 给他编写来帮助解决该问题的工具所取的一个诙谐的名称。TagSoup(参见 参考资料)是一个 Java 库,用于对 HTML 进行解析和清洁,并交付一个表示格式良好且有效的 XHTML 的 SAX 事件流。您也可以从命令行使用它来在脚本中执行类似的清洁工作。
我发现 TagSoup 非常可靠。该项目的座右铭是 "Just Keep On Truckin'",因为代码被设计来甚至对杂乱的 HTML 也作出很好的响应。它是开放源码的,您可以选择 GNU Public License 或者 Academic Free License(基于 BSD)。在本文中,我将展示如何从命令行使用 TagSoup。
设置和基本的使用
从项目页面下载小 JAR 文件 tagsoup-1.0rc4.jar(在撰写本文时,tagsoup-1.0rc4.jar 是可用的最新版本)。关于在 Java 5.0 下进行构建有一个重大的警告,但是您也许可以忽略它,因为您可能使用已经构建好的 JAR 文件。将 JAR 放在适当的地方,您就可以使用程序了。
清单 1 是一个格式不好的 HTML 文件的例子。
清单 1 (listing1.html). 格式不好的 HTML 例子
<HTML>
<HEAD>
<TITLE>Bad HTML example</TITLE>
<BODY>
<TABLE>
<TR>
<TD width=15>
<TD><FONT size="3"face="Helvetica">
Based on the "Journey to Windsor" example<BR>
by Benoît Marchal, but made much worse<BR>
</FONT></TD>
</TR>
</TABLE>
<CENTER><TABLE border=3>
<TR><TD>
<P>
<FONT size="3" face="Helvetica">See the definition of Tag Soup in
<A href="http://en.wikipedia.org/wiki/Tag_soup">
<IMG src="wikipedia-logo.png" border="0" alt="Wikipedia logo">
</a>
<P>This is a cut & dried mess.
</TD></TR>
</TABLE></CENTER>
</BODY>
</HTML>
除了一般的 XHTML 转换(比如将标记名称转换成小写的)之外,TagSoup 还解决以下这样的问题:
HEAD
、BR
、FONT
和P
缺少结束标记a
标记不匹配BORDER
属性没有用引号括住- 未转义的与符号(在最后一段中)
要在命令行调用 TagSoup,请使用您的 Java 运行时的 -jar 选项,例如 java -jar tagsoup-1.0rc4.jar listing1.html
。产生的清洁的 XHTML 在 清单 2 中,添加了一些新的行用于格式化。
清单 2. 从 TagSoup 和清单 1 得到的 XHTML 输出
<?xml version="1.0" standalone="yes"?> <html version="-//W3C//DTD HTML 4.01 Transitional//EN" xmlns="http://www.w3.org/1999/xhtml"> <head><title>Bad HTML example</title></head><body> <table><tr><td colspan="1" rowspan="1" width="15"> </td><td colspan="1" rowspan="1"><font size="3" face="Helvetica"> Based on the "Journey to Windsor" example<br clear="none"></br> by Benoît Marchal, but made much worse<br clear="none"></br> </font></td></tr></table> <center><table border="3"><tr><td colspan="1" rowspan="1"> <p> <font size="3" face="Helvetica">See the definition of Tag Soup in <a shape="rect" href="http://en.wikipedia.org/wiki/Tag_soup"> <img src="wikipedia-logo.png" border="0" alt="Wikipedia logo"></img> </a> </font></p><p>This is a cut & dried mess. </p></td></tr></table></center> </body></html>
注意,TagSoup 并不解决 HTML 中可能的每个坏实践。清单 2 是非常有效的 XHTML 1.0 转换,但是它使用了受到反对的元素,比如 font
和center
。您应该使用层叠样式表来表达这样的表示线索(presentation cues)。TagSoup 是一个用于清洁语法的工具,而不是语义层。如果您至少一开始使用清洁的语法,那么修正内容要容易得多。您然后可以使用 XML 工具。偶尔,TagSoup 会在 html
元素上使用受到反对的version
属性来跟踪关于源文档类型的信息。对于这一点来说,使用一个注释也许对 TagSoup 更好一些,以避免引入附加的受到反对的构造。
脚本技巧
了解如何从命令行使用 TagSoup 是将 HTML 清洁合并到脚本中的第一步。另一个强大的工具是 wget,该工具允许您从命令行取回 URL。您可以使用命令行将检索到的 HTML 直接从 wget 发送到 TagSoup:
wget -O - http://example.com/bad.html | java -jar tagsoup-1.0rc3.jar
我在一些恐怖的站点(我认为有趣的 "Web Pages that Suck" 站点)测试了该脚本,但是上面使用一个假的 URL 来保护这些站点。我敢保证您可以想到很多可以用于试验的可怕的 HTML。-O
选项告诉 wget 使用什么文件名来保存检索到内容,而 -
是一个特殊的值,用于将该文件发送到标准输出。该文件然后被发送到 TagSoup,我调用 TagSoup 时没有使用输入文件名,这导致它从标准输入读取数据。
另一个技巧是使用 -html
标志使 TagSoup 生成有效的 HTML 而不是 XHTML。这对于清洁还没有准备好完全与格式良好的 XML 一致的系统中大量遗留的 HTML 是很有用的。
工具应用
Url:https://github.com/stefanhaustein/html5index
该工具是将w3c的文档提取生成html5 js index,方便查询js api,相关代码:
public static Document loadDom(String url) {
Parser parser = new Parser();
try {
parser.setFeature(Parser.namespacesFeature, false);
parser.setFeature(Parser.namespacePrefixesFeature, false);
Reader reader = openReader(url);
DOMResult result = new DOMResult();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new SAXSource(parser, new InputSource(reader)), result);
reader.close();
return (Document) result.getNode();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
结束语
在本文中,学习了 TagSoup 以及它相对于 HTML Tidy 的一些优势。学习了如何从命令行调用 TagSoup,包括如何将它与其他命令行工具如 wget 一起使用。TagSoup 并不具有 HTML Tidy 具有的很多用于控制输入和输出的所有选项,但是它利用它的可靠性和速度弥补了这一点。当您被可怕的 HTML 所困扰时,请首先考虑用 TagSoup 来减轻您的痛苦。