【Cocos2d-x】支持 i18n 国际化(2)——i18n XML 解析生成头文件

本文介绍如何使用Python脚本解析Cocos2d-x项目的XML文件,提取字符串key生成头文件,实现国际化支持。脚本列举指定文件夹中的XML配置文件,提取唯一key,按namespace整理并写入头文件,帮助开发者避免硬编码字符串,便于编译期检查错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Cocos2d-x】支持 i18n 国际化(2)——i18n XML 解析生成头文件


转载请注明出处http://blog.csdn.net/arnozhang12/article/details/49784641


1、概述

        接 上一节,本节将使用 Python 脚本对 Resources/i18n 文件夹下的文件进行解析,将各个字符串的 key 提取出来,生成一个头文件,供我们使用。解决的问题:

  • 自动解析 XML 生成 key 供我们使用;
  • C++ 代码中,我们直接使用 namespace 下的常量替代 Hardcode 字符串,防止 key 值变化后,需要替换源代码中所有的 key;
  • 遇到不认识的 key,直接可以在编译期发现,而不是在运行期得不到字符串了。

        比如,我们有一个配置文件如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">射击场</string>
    <string name="start_game">开始游戏</string>
    <string name="exit_game">结束游戏</string>
    <string name="exit_comfirm_tips">确定要退出游戏吗?</string>
    <string name="cancel">取消</string>
    <string name="exit">结束</string>
    <string name="score">得分:</string>
</resources>

        我们希望在最终的 Classes/i18n.h 头文件中生成所有的 key:

//
// i18n.h
//
#pragma once

namespace res {

    namespace string {

        const char* const app_name = "app_name";
        const char* const start_game = "start_game";
        const char* const exit_game = "exit_game";
        const char* const exit_comfirm_tips = "exit_comfirm_tips";
        const char* const cancel = "cancel";
        const char* const exit = "exit";
        const char* const score = "score";
    }
}

2、使用方法

        那么使用的方法就非常简单了:

auto label = Label::create();
label->setString(i18n::getString(res::string::app_name));
label->setTextColor(Color4b::RED);
label->setSystemFontSize(40);

// ...

layer->addChild(label);

3、Python 脚本

        Python 脚本也非常简单,通过 os.listdir 列举出 Resources/i81n/ 文件夹下的配置文件,将各个文件进行解析,把 key 归类去重,按 namespace 规整,写到 Classes/i18n.h 头文件中即可。

#!/usr/bin/env python
#-*-conding:utf8-*-
#
# @author arnozhang
# @date   2015.11.11
# @email  zyfgood12@163.com

import sys;
import os;
import xml.dom.minidom;


I18N_PATH = './Resources/i18n/'
i18n_key_list = []


def new_indent_str(indent = 1):
    return ' ' * indent * 4


def is_xml_node(node, name):
    return node \
        and node.nodeType == xml.dom.Node.ELEMENT_NODE \
        and node.nodeName == name


#
# namespace res {
#     namespace string {
#         const char* const KEY_XXX = "xxx";
#     }
# }
#
def generate_i18n(file):
    indent_str = new_indent_str()
    res_indent_str = indent_str + indent_str

    file.write('namespace res {\n\n')
    file.write(indent_str + 'namespace string {\n\n')

    list = os.listdir(I18N_PATH)
    if list:
        for path in list:
            generate_by_file(file, I18N_PATH + path, res_indent_str)

    file.write(indent_str + '}\n')
    file.write('}\n')


def generate_by_file(file, res_file_path, res_indent_str):
    dom_tree = xml.dom.minidom.parse(res_file_path)
    if not dom_tree:
        return

    #
    # <resources>
    #   <string name="KEY_XXX">xxx</string>
    # </resources>
    #
    for res in dom_tree.documentElement.childNodes:
        if is_xml_node(res, 'string'):
            key_name = res.getAttribute('name')
            if not (key_name in i18n_key_list):
                i18n_key_list.append(key_name)
                write_string_res(file, key_name, res_indent_str)


def write_string_res(file, key_name, res_indent_str):
    file.write(res_indent_str)
    file.write('const char* const %s = "%s";\n' % (key_name, key_name))


if __name__ == '__main__':
    file = open('./Classes/I18n.h', mode = 'w')
    file.write('#pragma once\n\n')

    generate_i18n(file)

    file.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值