用 Python 管理 Android 中 strings.xml 的字符翻译
2015-07-15 17:26
741 查看
对于一个带有多种语言的 Android 应用。如果要修改某个字符某种语言的翻译,就要去修改该语言对应的
根据上述
其中,第一行表示了 Android 应用中不同语言的语言简码。例如,我们的应用中有中文、法语、西班牙语和德语,那么对应的表格第一行就有 zh、fr、es和de。
表格中的第一列则对应
表格中剩下的部分对应
由于
其中,我们将
接下来,我们对提取出来的内容做进一步的分解。将第一行的语言简码保存到
Note: Android 中,不同语言的
获取语言简码的代码如下:
最后,将字符的变量名和对应的字符翻译放到一个字典
其中,
在这个地方,本来是用
但是由于在 Python 中,字典是无序的。这样会导致产生字典的字符顺序与最初 Excel 表格的字符顺序不一致。下面是用
可以看到用
补充:
下面提供一种更加简单的方法来生成
然后,就是调用 Python 的
最后,生成
strings.xml文件字符的内容。这样操作比较麻烦,也容易出错。于是,就想着利用 Excel 表格的可读性和易于管理性,通过 Python 脚本将 Excel 表格转化成
strings.xml对应的字符。该脚本的源码见:https://github.com/heray1990/txt2xml。
构建 Excel 表格
假设在我们的 Android 应用里,values-zh/目录下的
strings.xml文件内容如下:
<?xml version="1.0" ?> <resources> <string name="Main.MenuShowHistory">历史</string> <string name="Main.MenuShowDownloads">下载</string> <string name="Main.MenuPreferences">配置</string> <string name="PreferencesActivity.EnableJavascriptPreferenceSummary">如果不支持JavaScript,很多网站效果不能打开,建议打开.</string> </resources>
根据上述
strings.xml文件的内容,我们在 Excel 中创建类似如下表格(翻译不一定准确,仅供参考):
zh | fr | es | de | |
Main.MenuShowHistory | 历史 | Historique | Historial | Verlauf |
Main.MenuShowDownloads | 下载 | Téléchargements | Descargas | Downloads |
Main.MenuPreferences | 配置 | Préférences | Preferencias | Einstellungen |
PreferencesActivity.EnableJavascriptPreferenceSummary | 如果不支持JavaScript,很多网站效果不能打开,建议打开. | Active ou désactive le JavaScript. | Activar o desactivar JavaScript. | JavaScript ein-/ausschalten. |
表格中的第一列则对应
strings.xml文件中
<string>节点
name属性的值。
表格中剩下的部分对应
strings.xml文件中
<string>节点的值。例如:“历史”就是
Main.MenuShowHistory对应的中文翻译。
生成 Unicode txt 文件
构建完 Excel 表格之后,将内容保存到 Unicode txt 文件中。即在 Excel 软件里面:另存为 -> Unicode 文本(*.txt)。这样就生成了 Python 可以解析的 txt 文件(假设我们这里的文件名字为:strings.txt)。内容如下:
zh fr es de Main.MenuShowHistory 历史 Historique Historial Verlauf Main.MenuShowDownloads 下载 Téléchargements Descargas Downloads Main.MenuPreferences 配置 Préférences Preferencias Einstellungen PreferencesActivity.EnableJavascriptPreferenceSummary 如果不支持JavaScript,很多网站效果不能打开,建议打开. Active ou désactive le JavaScript. Activar o desactivar JavaScript. JavaScript ein-/ausschalten.
解析 Unicode txt 文件
注意到,从 Excel 表格生成的strings.txtUnicode txt 文件里,每个单元格之间使用制表符
'\t'隔开。在解析的时候可以通过检测制表符来获取每个单元格的内容。
由于
strings.txt的内容是以 Unicode 进行编码,因此需要先将 Unicode 转成 utf-8,便于后面的字符处理。这要用到
codecs模块,此部分的代码如下:
cwd = os.path.dirname(sys.argv[0]) self.txt_fd = codecs.open(os.path.join(cwd,txt_fname),'r','utf-16') ls = [line.strip().encode('utf-8') for line in self.txt_fd] self.txt_fd.close()
其中,我们将
strings.txt文件中的每一行作为列表的一个元素保存到列表
ls中。此时,我们已经初步将
strings.txt的内容提取出来。
接下来,我们对提取出来的内容做进一步的分解。将第一行的语言简码保存到
self.langls列表中,用于后面根据不同的语言生成不同的
values-*目录。
Note: Android 中,不同语言的
strings.xml文件被放到不同的
values-*目录。例如,中文的
strings.xml文件会放到
values-zh目录。而
zh就是对应于 Excel 表格第一行(
ls[0])的语言简码。
获取语言简码的代码如下:
self.langls = ls[0].split('\t')
最后,将字符的变量名和对应的字符翻译放到一个字典
self.stringdict中。其中变量名为 key,字符的翻译为 value。以字典的形式保存字符翻译,便于后面的操作。这部分的代码如下:
lskey = [] lsval = [] for i in ls[1:]: subls = i.split('\t') lskey.append(subls[0]) lsval.append(subls[1:]) self.stringdict = collections.OrderedDict(zip(lskey,lsval))
其中,
lskey列表保存了表格中第一列的字符变量名。该列表的内容应该如下:
['Main.MenuShowHistory', 'Main.MenuShowDownloads', 'Main.MenuPreferences', 'PreferencesActivity.EnableJavascriptPreferenceSummary']
lsval列表则保存了字符翻译的值,该列表的内容如下:
[['\xe5\x8e\x86\xe5\x8f\xb2', 'Historique', 'Historial', 'Verlauf'], ['\xe4\xb8\x8b\xe8\xbd\xbd', 'T\xc3\xa9l\xc3\xa9chargements', 'Descargas', 'Downloads'], ['\xe9\x85\x8d\xe7\xbd\xae', 'Pr\xc3\xa9f\xc3\xa9rences', 'Preferencias', 'Einstellungen'], ['\xe5\xa6\x82\xe6\x9e\x9c\xe4\xb8\x8d\xe6\x94\xaf\xe6\x8c\x81JavaScript\xef\xbc\x8c\xe5\xbe\x88\xe5\xa4\x9a\xe7\xbd\x91\xe7\xab\x99\xe6\x95\x88\xe6\x9e\x9c\xe4\xb8\x8d\xe8\x83\xbd\xe6\x89\x93\xe5\xbc\x80\xef\xbc\x8c\xe5\xbb\xba\xe8\xae\xae\xe6\x89\x93\xe5\xbc\x80.', 'Active ou d\xc3\xa9sactive le JavaScript.', 'Activar o desactivar JavaScript.', ' JavaScript ein-/ausschalten.']]
collections.OrderedDict(zip())函数可以将两个列表转换成一个字典。下面是一个关于该函数的例子:
>>> a = ['a','b','c'] >>> b = [[1,2,3],[4,5,6],[7,8,9]] >>> zip(a,b) [('a', [1, 2, 3]), ('b', [4, 5, 6]), ('c', [7, 8, 9])] >>> import collections >>> collections.OrderedDict(zip(a,b)) OrderedDict([('a', [1, 2, 3]), ('b', [4, 5, 6]), ('c', [7, 8, 9])])
在这个地方,本来是用
dict()函数的,即
self.stringdict = dict(zip(lskey,lsval))
但是由于在 Python 中,字典是无序的。这样会导致产生字典的字符顺序与最初 Excel 表格的字符顺序不一致。下面是用
dict()函数的例子:
>>> a = ['a','b','c'] >>> b = [[1,2,3],[4,5,6],[7,8,9]] >>> zip(a,b) [('a', [1, 2, 3]), ('b', [4, 5, 6]), ('c', [7, 8, 9])] >>> dict(zip(a,b)) {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
可以看到用
dict()函数输出的字典键值对的顺序与输入的时候不一致。而
collections.OrderedDict()则可以保证输入输出前后字典键值对的顺序一致。
补充:
下面提供一种更加简单的方法来生成
self.stringdict(上面的方法有点啰嗦,其实字典是可以直接地构建的):
for i in ls[1:]: subls = i.split('\t') self.stringdict[subls[0]] = subls[1:]
生成 strings.xml 文件
首先,我们要根据前面提到的self.langls列表来生成不同语言的目录
values-*。下面是这部分的代码:
for j in self.langls: # Create the directories according to the language. os.mkdir(XML_FILE_DIR_PREFIX + j)
然后,就是调用 Python 的
xml.dom.minidom模块构建 XML 的节点和相关的内容。其中,字符对应语言的翻译是从
self.stringdict字典提取出来。相关代码如下:
doc = Document() resources = doc.createElement("resources") doc.appendChild(resources) for k,v in self.stringdict.items(): stringele = doc.createElement("string") stringele.setAttribute("name",k) text = doc.createTextNode(v[self.langls.index(j)]) stringele.appendChild(text) resources.appendChild(stringele)
最后,生成
strings.xml文件:
uglyXml = doc.toprettyxml(indent=' ') text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL) prettyXml = text_re.sub('>\g<1></', uglyXml) self.xmlfd = open(os.path.join(XML_FILE_DIR_PREFIX + j,XML_FILE_NAME),'w') #doc.writexml(self.xmlfd) self.xmlfd.write(prettyXml) self.xmlfd.close()
相关文章推荐
- Python 爬虫学习
- Python映射类型、集合类型
- 自己做的一个python分页的自定义方法
- python基础教程总结7——异常
- Python中'__main__'模块的作用
- Python学习笔记4_字符串
- python md5加密中文
- Python脚本刷点击率。
- 5-python学习——条件语句
- Numpy 入门
- 原创翻译-值得关注的10个python语言博客
- Python进阶三:面向对象基础
- Python序列:字符串、元组、列表
- Python的Django框架中if标签的相关使用
- python程序的pdb调试方法
- python 实现发送邮件
- 在Python的Django框架中调用方法和处理无效变量
- python 使用multiprocessing需要注意的问题
- Python学习笔记——ADO访问数据库
- Python 之 数据类型、类与对象