[技术贴]用Python 2.3操作XML时遇到的编码问题

最近在学习Python。不过因为Python2.3不支持GB2312编码,而我的程序需要用到中文,只好用了标准的UTF-8编码。

用了一个月也没有发现什么问题,不过周一时,当我需要通过minidom修改一个XML文件中的TextNode里的中文文本时,在保存时就会出错。查来查去找不到问题所在,令狐说Python有一个SIG(特别兴趣小组)专门处理XML的,有一个PyXML。于是我又下载了这个东东装上,但是还是有问题。

不过倒发现这个PyXML里面带了一个XPath的实现,简直是太好了,有这个东东我可以省很多代码。

因为正则表达式处理的需要,我要先把原始字符串从GB码转成UTF-8:

content = unicode( content, "mbcs" )
content = codecs.getencoder( "utf-8" )( content )[0]

这样的串在内部是以UTF-8编码的ASCII串存在的。当写入XML的TextNode时,就会把它当作ASCII编码转成UNICODE,因为它原来已经是UTF-8编码的,这样在XML保存时,就会再进行一次ASCII到UTF-8的转换,因为UTF-8的代码范围超过ASCII的范围,所以被当作错误ASCII码导致异常。

解决的办法也很简单,就是在写入XML的TextNode时,把要写入的内容指定为UTF-8编码的UNICODE:

node.replaceChild( doc.createTextNode( unicode( newtext, "utf-8" ) ), node.firstChild )

当然,保存为XML文件时也要注意,不能直接以ASCII文件的方式保存,而要指定成UTF-8编码的文件,方法如下这样通过codecs:

def saveToFile( file_name, content ) :
f = codecs.open( file_name, "w", "utf-8" )
f.write( content )
f.close( )

最后,如果要保存前面那个UTF-8编码的ASCII串content,同样需要转换为UTF-8的UNICODE才行:

saveToFile( "content.htm", unicode( content, "utf-8" ) )

更多关于Python中用UNICODE处理中文的技术细节,参考令狐推荐的这篇《[Python学习]Unicode及编码处理心得

5 Replies to “[技术贴]用Python 2.3操作XML时遇到的编码问题”

  1. 是啊是啊,又碰到新的编码问题。比如mblogger是用GB2312的,但是没有在meta里指定,我想程序里默认用GB2312吧,结果donews又是UTF-8的,也居然TNND没用meta指定编码,还是CSDN比较厚道,用了UTF-8并且还有meta指定了。

  2. 终于找到组织了,我在Jython(Python的Java版)和Jacl(Tcl/Tk的Java版)里摸爬滚打一年了,对Python靠行对齐来分别区段code还在狂faint不已,用个方括号,尖括号,大括号括起来不就得了么!

Leave a Reply

Your email address will not be published. Required fields are marked *