lax文件的编码问题
解析blackberry的设备应用文件alx,格式是xml的,但文件没有标明编码,也没有<?xml version="1.0" ?>类似的标注。文件的编码,尤其是要读取未知编码的文件,是比较痛苦的事。在linux下,可以通过file命令来获取文件的编码
file -i BlackBerry.alx
会得到类似下边的结果,可以看出其编码iso-8859-1
BlackBerry.alx: text/plain; charset=iso-8859-1
详细了解file命令查看这里
可以看到alx文件的编码是iso-8859-1
它的一个别名是Latin-1
# 读取文件内容,并转为utf-8编码,
fp = codecs.open(filepath, 'r', 'latin-1')
content = fp.read().encode('utf-8', errors="xmlcharrefreplace")
fp.close()
# 之后用minidom来解析改文件
xmldoc = minidom.parseString(content)
# ...deal with xmldoc
#保存修改后的文件
xmlstr = xmldoc.toxml() #默认是unicode字符串,也可以指定编码
# 转码,其中包含中文和其他一些字符是无法转为latin-1编码的,一定要指定errors的处理方式
content = xmlstr.encode('latin-1', errors="xmlcharrefreplace")
#errors的详细处理信息 http://docs.python.org/library/codecs.html
fp = open(filename, "w")
fp.write(content)
fp.close()
如果只到此,用diff工具查看原文件和修改过后的文件,会发现很多不同,而且修改后的文件无法被正确读取,
认真查看这些不同处,会发现,其中一大部分是由于xml的标签的属性间位置的改变,这个不影响读取
余下的不同处,会发现是类似核和核之间的不同,前者用十六进制表示unicode编码,后者用十进制表示
按理这个应该是一样的,但使用后者,原程序就是无法识别,所以后者必须转换成前者
通过正则表达式来替换
def hexrepl(match):
value = int(match.group(1))
hex_str = str(hex(value))[2:]
count = len(hex_str)
for _ in xrange(4-count):
hex_str = "0%s"% hex_str
return "&#x%s;"% hex_str
p = re.compile(r'&#(\d+);')
content = p.sub(hexrepl, content)

浙公网安备 33010602011771号