4.7. 给属性值加引号

comp.lang.python 上的一个常见问题是“我有一些 HTML 文档,属性值没有用引号括起来,并且我想将它们全部括起来,我怎么才能实现它呢?”[10] (一般这种事情的出现是由于一个项目经理加入到一个大的项目中来,而他又抱着 HTML 是一种标记语言的教条,要求所有的页面必须能够通过 HTML 校验器的验证。而属性值没有被引号括起来是一种常见的对 HTML 规范的违反。)不管什么原因,未括起来的属性值通过将 HTML 送进 BaseHTMLProcessor 可以容易地修复。

BaseHTMLProcessor 消费(consume)HTML (因为它是从 SGMLParser 派生来的)并生成等价的 HTML。但是这个 HTML 输出与输入的并不一样。标记和属性名最终会转化为小写字母,即使它们可能以大写字母开始或是大小写的混和形式。属性值将被双引号引起来,即使它们原来可能是用单引号括起来的或根本没有括起来。这就是最后我们可以受益的边际效应。

例 4.15. 括起属性值

>>> htmlSource = """        1
...     <html>
...     <head>
...     <title>Test page</title>
...     </head>
...     <body>
...     <ul>
...     <li><a href=index.html>Home</a></li>
...     <li><a href=toc.html>Table of contents</a></li>
...     <li><a href=history.html>Revision history</a></li>
...     </body>
...     </html>
...     """
>>> from BaseHTMLProcessor import BaseHTMLProcessor
>>> parser = BaseHTMLProcessor()
>>> parser.feed(htmlSource) 2
>>> print parser.output()   3
<html>
<head>
<title>Test page</title>
</head>
<body>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="toc.html">Table of contents</a></li>
<li><a href="history.html">Revision history</a></li>
</body>
</html>
1 请注意,在 a 标记中的 href 属性值没有被适当的括起来(还要注意,除了文档字符串之外,我们还将三重引号用到了其它的地方,并且是不会少于直接在 IDE 中的使用。它们非常有用。)
2 装填分析器。
3 使用定义在 BaseHTMLProcessor 中的 output 函数,我们得到单个字符串的输出,并且属性值被完全括起来了。让我们想一下这里实际上发生了多少事:SGMLParser 分析整个 HTML 文档,将其分解为一片片的标记、引用、数据等等。BaseHTMLProcessor 使用这些元素来重新构造 HTML 的片段(如果你想查看的话它们仍然保存在 parser.pieces中)。最后,我们调用 parser.output,它将所有的 HTML 片段连接成一个字符串。

脚注

[10] 好吧,其实并不是那么普通的一个问题。在那不都是问“我应该用何种编辑器来写Python代码?“(回答:Emacs)或“ Python比Perl是好还是坏?”(回答:“Perl比Python差,因为人们想让它差的。” -Larry Wall,1998年10月14日)但是关于 HTML 处理的问题,或者这种提法或者另一种提法,大约一个月就要出现一次,在这些问题之中,这个问题是最常见的一个。