《Python Cookbook(第2版)中文版》——1.23 对Unicode数据编码并用于XML和HTML

1.23 对Unicode数据编码并用于XML和HTML

任务

你想对Unicode文本进行编码,使用一种有限制,但很流行的编码,如ASCII或Latin-1,并将处理后的结果用于HTML输出或者某些XML应用。

解决方案

Python提供了一种编码错误处理工具,叫做xmlcharrefreplace,它会将所有不属于所选编码的字符用XML的数字字符引用来替代:

def encode_for_xml(unicode_data, encoding='ascii'):
      return unicode_data.encode(encoding, 'xmlcharrefreplace')

也可以将此法用于HTML输出,不过你可能会更喜欢HTML的符号实体引用。出于这个目的,需要定义并注册一个自定义的编码错误处理函数。要实现这样一个处理函数非常简单,因为Python标准库已经提供了一个叫做htmlentitydefs的模块,包含了所有的HTML实体定义:

import codecs
from htmlentitydefs import codepoint2name
def html_replace(exc):
      if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)):
             s = [ u'&%s;' % codepoint2name[ord(c)]
                       for c in exc.object[exc.start:exc.end] ]
             return ''.join(s), exc.end
      else:
             raise TypeError("can't handle %s" % exc._ _name_ _)
codecs.register_error('html_replace', html_replace)

注册完错误处理函数之后,可以再写个包装函数,以简化使用:

def encode_for_html(unicode_data, encoding='ascii'):
      return unicode_data.encode(encoding, 'html_replace')

讨论

如同其他的一些Python模块一样,这个模块也将提供一个测试的示例,由if _name == ' main _'这一行语句进行保护:

if _ _name_ _ == '_ _main_ _':
      # demo
      data = u'''\
<html>
<head>
<title>Encoding Test</title>
</head>
<body>
<p>accented characters:
<ul>
<li>\xe0 (a + grave)
<li>\xe7 (c + cedilla)
<li>\xe9 (e + acute)
</ul>
<p>symbols:
<ul>
<li>\xa3 (British pound)
<li>\u20ac (Euro)
<li>\u221e (infinity)
</ul>
</body></html>
'''
      print encode_for_xml(data)
      print encode_for_html(data)

如果将此模块作为主脚本来运行,你会看到如下的输出(来自于encode_for_xml):

<li>à (a + grave)
<li>ç (c + cedilla)
<li>é (e + acute)
    ...
<li>£ (British pound)
<li>€ (Euro)
<li>∞ (infinity)

还有这些(来自于encode_for_html):

<li>&agrave; (a + grave)
<li>&ccedil; (c + cedilla)
<li>&eacute; (e + acute)
    ...
<li>&pound; (British pound)
<li>&euro; (Euro)
<li>&infin; (infinity)

这两段输出都很清晰,不过encode_for_xml更加具有通用性(它可以用于任何XML应用,不仅仅是HTML),但encode_for_html却能够生成更易读的结果—如果希望直接读取或者编辑那些结果。如果给浏览器提供这两种形式的数据,能够看到渲染输出实际上是一样的。为了看到这两种方式在浏览器中的展示,可以将上述代码作为主脚本运行,将输出导向到一个磁盘文件,并用文本编辑器将这两种输出分隔开来,然后用浏览器分别查看。(再或者,运行脚本两次,一次将调用encode_for_xml的输出注释掉,一次将encode_for_html的输出注释掉)。

请记住,Unicode数据在被打印或者写到文件之前一定要先编码。由于UTF-8能够处理任何Unicode字符,所以它是理想的编码。但对很多用户和应用而言,ASCII或Latin-1比UTF-8更受欢迎。当Unicode数据包含了指定编码之外的字符时(比如,一些重音字符和很多符号大多不在ASCII或Latin-1之中,比如,Latin-1无法表现“无穷”符号),单靠这些编码本身,根本无法处理这些数据。Python提供一个内建的编码错误处理函数,叫做xmlcharrefreplace,将所有的不能被编码的字符替换为XML的数字字符引用,比如“∞”,表示“无穷”符号。本节还展示了怎样编写和注册另一个类似的错误处理函数html_replace,针对HTML输出进行处理。html_replace将不能编码的字符替换为更具可读性的HTML符号实体引用,比如用“∞”来表示“无穷”符号。html_replace相比于xmlcharrefreplace,它的通用性没那么好,因为它并不支持所有的Unicode字符,同时也不能用于非HTML的应用;但如果你希望HTML输出的源码文件能够具有更好的可读性,html_replace是非常有用的。

如果输出的不是HTML或者任何形式的XML,这些错误处理函数就没什么意义了。比如,TeX和其他的标记语言并不认识XML的数字字符引用,但如果你知道怎样创建一个该标记语言中的字符引用,可以修改本节示例中的错误处理函数html_replace,并注册一个新的符合需求的处理函数。

当需要将Unicode数据写入文件时,可以使用Python标准库的codecs模块提供的另一个(非常高效)可以指定编码和错误处理函数的方法:

outfile = codecs.open('out.html', mode='w', encoding='ascii',
                                   errors='html_replace')

现在,可以将outfile.write(unicode_data)应用于任何Unicode字符串unicode_data,所有的编码和错误处理都会透明地自动进行。当然,在输出完成之后,还得调用outfile.close()。

时间: 2024-08-03 09:59:11

《Python Cookbook(第2版)中文版》——1.23 对Unicode数据编码并用于XML和HTML的相关文章

《Python Cookbook(第2版)中文版》——导读

前 言 这本书不是一本典型的O'Reilly风格的书,而是一本集合了多个作者的手稿的作品.实际上,这也是一种将开源开发的方式应用到书籍出版业的尝试.Python社区有超过300个成员在本书中贡献了他们的心得和资料.在这里,我们作为编辑,想给你--本书的读者,介绍一些重要的背景资料,这些背景资料是关于此书是如何编著出来,以及这个过程和涉及的人,并提出一些关于这种崭新的风格的思考. 目 录 [第1章 文本1.1 每次处理一个字符](https://yq.aliyun.com/articles/963

谁有&amp;amp;lt;&amp;amp;lt;CLR Via C#&amp;amp;gt;&amp;amp;gt;第三版中文版的电子书

问题描述 谁有<<CLRViaC#>>第三版中文版的电子书,我是个初学者,看网上推荐此书的人多,想看一下,我的QQ:330784617.谢谢!! 解决方案 解决方案二:试一试我一般看英文的,虽然很少看书:(解决方案三: 解决方案四:第二版有的,想看第三版.

拒绝从入门到放弃_《Python 核心编程 (第二版)》必读目录

目录 目录 关于这本书 必看知识点 最后 关于这本书 <Python 核心编程 (第二版)>是一本 Python 编程的入门书,分为 Python 核心(其实并不核心,应该叫基础) 和 高级主题 两大部分,以 Python 2.x 作为主要演示版本,涵盖的知识面广,知识点较齐全,代码多且好理解,但对 Python 版本特性的内容太久远,不合时宜. 整体来说 Python 核心 部分是主要内容,高级主题 部分作为应用扩展内容.后半部分篇幅较短,内容不够深入,只到了解的层面,好在横向够广(每一个主

(六十二)第四章总结——《C++ Primer Plus 第6版 中文版》

书是<C++ Primer Plus  第6版  中文版> 数组.指针.结构 是C++的3种复合类型.   注:为了方便,类型名用int为主,变量名用a为主.   数组: 包括数组(例如int a[10];)和字符串(例如char a[10];),还有string类(例如string a="abc";),vector类(例如vector<int>a(5)).array类(array<int,3>a)等. 数组名表示数组所在的(第一个元素)内存地址.

求大神解答一下-C++ primer plus 第6版 中文版 第16章复习题的一个问题

问题描述 C++ primer plus 第6版 中文版 第16章复习题的一个问题 奇葩的是课后居然没答案...... 求正规.严谨.简洁的标准答案! 程序清单16.15(在p708页):functor.cpp //functor.cpp--using a functor #include尖括号iostream尖括号 #include尖括号list尖括号 #include尖括号iterator尖括号 #include尖括号algorithm尖括号 template//functor class

【转】c++.primer.plus.第五版.中文版[下载]

c++.primer.plus.第五版.中文版[下载] 一共有5部分.全部下载完才可解压阅读. c++.primer.plus.第五版.中文版(一) c++.primer.plus.第五版.中文版(二) c++.primer.plus.第五版.中文版(三) c++.primer.plus.第五版.中文版(四) c++.primer.plus.第五版.中文版(五) "在遇到无法解决的问题时,我总会求助于C++ Primer一书."--Bruce Eckel,"编程思想"

任天堂宣布《勇者斗恶龙9》北美版7月11日发售,欧版7月23日发售

Nintendo日前宣布<勇者斗恶龙9>将在7月登陆欧美,北美版7月11日发售,欧版7月23日发售. SE之前的财报显示,<勇者斗恶龙9>日本销量突破426万套,去年7月发售,首周销量为230万套.

《Python 3程序开发指南(第2版•修订版)》——7.3 写入与分析XML文件

7.3 写入与分析XML文件 有些程序将其处理的所有数据都使用XML文件格式,还有些其他程序将XML用作一种便利的导入/导出格式.即便程序的主要格式是文本格式或二进制格式,导入与导出XML的能力也是有用的,并且始终是值得考虑的一项功能. Python提供了3种写入XML文件的方法:手动写入XML:创建元素树并使用其write()方法:创建DOM并使用其write()方法.XML文件的读入与分析则有4种方法:人工读入并分析XML(不建议采用这种方法,这里也没有进行讲述--正确处理某些更晦涩和更高级

《Python Cookbook(第2版)中文版》——1.15 扩展和压缩制表符

1.15 扩展和压缩制表符 任务 将字符串中的制表符转化成一定数目的空格,或者反其道而行之. 解决方案 将制表符转换为一定数目的空格是一种很常见的需求,用Python的字符串提供的expandtabs方法可以轻松解决问题.由于字符串不能被改变,这个方法返回的是一个新的字符串对象,是原字符串的一个修改过的拷贝.不过,仍可以将修改过的拷贝绑定到原字符串的名字: mystring = mystring.expandtabs( ) 这样并不会改变mystring原先指向的字符串对象,只不过将名字myst