转换M8的XML通讯录为通用的VCard(VCF)格式
Xiaoxia 2012-02-08 02:54
自从2011年某月某日,在广州大学城的公交上丢了手机之后,就一直用者同学的旧手机。过年后,钱够了,就打算买手机!于是,把以前M8的通讯录转换为Android可以导入的VCF文件。
Android2.3使用的VCard版本为3.0,我导出了一个样例用于分析:
BEGIN:VCARD
VERSION:3.0
N:黄;小虾;;;
FN:黄小虾
TEL;TYPE=CELL:13800138000
TEL;TYPE=WORK:02010086
EMAIL;TYPE=WORK:xiaoxia@xiaoxia.org
ADR;TYPE=WORK;CHARSET=UTF-8:;;c12-151;广州;广东;510006;
URL:xiaoxia.org
PHOTO;ENCODING=B;TYPE=PNG:iVBOR(... 此处省略编码后的图片数据)CYII=
X-QQ:10000
END:VCARD
从上面样例可以猜出VCard的大致格式。使用(\r\n)换行表示多个键,冒号(:)把键名和键值分开。分号(;)用来加入参数。
Name[;Attribute=AttributeValue]:Value[;MoreValue]
对上述样例中用到的键名的解释:
BEGIN:VCARD 用于开始一个VCard记录。 VERSION:3.0 VCard的版本。 N:姓氏;名字;中间名;尊称(先生、女士、小姐);不知道 FN 格式化的显示全名 TEL 电话号码 EMAIL 电子邮件 URL 网站 ADR 地址 PHOTO 个人照片 X-QQ QQ号码 X-TWITTER Twitter用户名 END:VCARD 一个VCard记录的结束。
再来研究一下M8里备份的通讯录的格式,下面是我抽取的一个示例。
文件名 mycontact.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <ContactTable> <Contact> <FileAs>楚中天</FileAs> <FirstName>中天</FirstName> <LastName>楚</LastName> <Phone> <PhoneElement IsPrimary="1" Value="10086" Type="0" /> <PhoneElement IsPrimary="0" Value="13800138000" Type="0" /> </Phone> </Contact> <Contact> <FileAs>林蛋大</FileAs> <FirstName>蛋大</FirstName> <LastName>林</LastName> <Phone> <PhoneElement IsPrimary="1" Value="10010" Type="0" /> </Phone> </Contact> </ContactTable>
看起来,好像XML的更加易读,但是体积也会比VCF的体积要大。
下面写一小段Python代码来做这个格式转换的工作(又是Python哦,要是有别的语言写起来更简洁,我会考虑学习一下)。
#!/usr/bin/env python # coding: utf-8 from xml.etree import ElementTree as ET # 输出到的VCF文件 out = file("mycontact.vcf", "wb") # 从M8的XML通讯录读取每条记录。 root = ET.parse(file("mycontact.xml", "r")).getroot() for e in root.findall('Contact'): out.write('BEGIN:VCARD\r\nVERSION:3.0\r\n') out.write('N:%s;%s;;;\r\n' % (e.findtext('LastName', '').encode('utf8'), e.findtext('FirstName', '').encode('utf8'))) out.write('FN:%s\r\n' % (e.findtext('FileAs', '').encode('utf8'))) # 枚举号码条目 for ee in e.find('Phone').findall('PhoneElement'): primary = int(ee.get('IsPrimary')) out.write('TEL;TYPE=CELL%s:%s\r\n' % ( (';TYPE=PREF' if primary else ''), ee.get('Value'))) out.write('END:VCARD\r\n') out.close()
一开始运行遇到异常,原因是e.findtext('LastName', '')得到的值本应是utf8的,结果被Python转换成了unicode,所以最后还是要自己再encode为utf8。因为VCard文件编码必须为utf8。
执行转换后,结果如下:
文件名 mycontact.vcf
BEGIN:VCARD
VERSION:3.0
N:楚;中天;;;
FN:楚中天
TEL;TYPE=CELL;TYPE=PREF:10086
TEL;TYPE=CELL:13800138000
END:VCARD
BEGIN:VCARD
VERSION:3.0
N:林;蛋大;;;
FN:林蛋大
TEL;TYPE=CELL;TYPE=PREF:10010
END:VCARD
怎么样?体积小巧了,但是没有XML的那么有层次,那么容易看懂。
如果有时间的话,我打算用HTML5做一个在线给VCF通讯录的记录添加自定义照片的。觉得有需要的,请支持我
参考文献: