因为要求程序员自己知道一个魔术是不切实际的
表示特定消息的键,它代表
系统应提供一种符合人体工学的方法来以符号形式引用这些按键
方式(请记住上面的 MSG_Hello_World
的抽象示例。
根据 18n 和 l10n 的最佳实践,源字符串位于
XML 文件(此处命名为 strings.xml
),如下所述。一个
strings.xml
文件示例如下所示。
此文件旨在声明我们的程序所用的所有外部化字符串,
使用,并赋予其本地唯一的 name
。这些字符串将用作
进行转换,name
将用作符号
xml
<!-- comment -->
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- comment -->
<string
name="STRING_NAME"
>text_string</string>
<string
name="STRING_NAME_2"
>text_string_2</string>
<string
name="STRING_NAME_3"
>string with
an intervening newline</string>
</resources>
文件 strings.xml
会经历一系列转换,其中
由译者制作同一文件的不同语言版本。通过
翻译过程的输入-输出行为是:strings.xml
文件
用某种源(人类)语言编写的字符串和多种口味
共出 strings.xml
,每个文件都翻译成了一种特定的语言。
在大型企业中,整个翻译过程可能会相当复杂
因此,翻译工作可能涉及到
由生活在世界各地的翻译人员来完成
以及专用翻译工具的得分。而是精确的
对我们作为消费者来说并不重要,只要输入、输出、
流程的行为,我们也知道
可能需要一些时间才能完成翻译所生成的文件将转换为
,并且在同一 API 中与 Fuchsia 程序一起提供,
Fuchsia 软件包
,了解所有最新动态。
Fuchsia 软件包的一个重要特点是它们本身不是
而是按内容哈希指向文件的清单。因此
多个程序可以共享相同的文件,
("en-US", "en-GB") 可能会共享邮件磁盘空间。以下
图表简要概述了字符串的生命周期。
strings.xml
我们重复使用 Android 字符串资源 XML 格式来表示可本地化 字符串。由于我们不会向 strings.xml 格式添加任何内容, 将对功能的讨论被委派给字符串资源 页面。
虽然上图中的所有 XML 都让本次讨论看起来只是 从 20 世纪 90 年代直接相连的虫洞中形成的,XML 实际上是 非常适合用来描述带注释的文本。strings.xml 格式 并在 Android 中经过时间测试,这样我们就能确定它是否足够, 也非常熟悉
例如,字符串资源可以使用交错的注解进行声明 插入源文本中。
<!-- … -->
<string name="title"
>Best practices for <annotation font="title_emphasis">text</annotation> look like so</string>
<!-- … -->
上图:交错翻译文本和注解的示例。
可以交错显示应防止翻译的文字, 就像这样:
<string name="countdown">
<xliff:g id="time" example="5 days"
>{1}</xliff:g> until holiday</string>
上图:一个围栏关闭参数的交错示例,带有 示例值,并使用不属于字符串的标记进行保护 资源数据架构。
如有需要,我们还可以定义自己向数据架构添加的内容 在现有架构中透明交错该数据架构。
上述文件的内容有一些必要的约束:
- 文件中的每个
name
属性都必须是唯一的。 - 名称标识符可以包含大写和小写 ASCII 字母、数字和下划线,但不能以数字开头。例如,允许使用
_H_e_L_L_o_wo_1_rld
,但不允许使用0cool
。 - 文件中的
name
-message
组合不得重复。
目前还没有关于在单个网域内添加多个字符串文件的规定 项目。
消息标识符
消息标识符(每条消息的“神奇”数字常量)是
根据 strings.xml
文件的内容生成。每个字符串
消息会获得一个唯一标识符,该标识符是根据单向哈希计算得出的
name
以及消息本身的内容。此标识符分配
可以确保两种不同的消息
意外地获得了相同的生成的标识符。
这些消息由 GN 构建规则在 Fuchsia 中,但最终是 由名为 strings_to_fidl. 此程序为消息 ID 生成 FIDL 中间表示法, 而常规的 FIDL 工具链用于生成特定语言版本的 这些信息。例如,C++ 风味是包含 以下内容:
namespace fuchsia {
namespace intl {
namespace l10n {
enum class MessageIds : uint64_t {
STRING_NAME = 42u,
STRING_NAME_2 = 43u,
STRING_NAME_3 = 44u,
};
} // namespace l10n
} // namespace intl
} // namespace fuchsia
分配给上例中每个特定枚举值的精确值 并不相关。目前,生成方法也不相关, 因为所有标识符都是在编译时生成的,没有机会 针对版本偏差进行优化。目前,我们可以放心地假设 组合将始终分配相同的邮件 ID。
将结果文件添加到 C++ 程序中非常简单。最小
示例如下,但请参考针对
线缆的精确细节库参数 fuchsia.intl.l10n
为
由作者直接作为标记提供给 strings_to_fidl
;或者,如果
使用适当的 GN 模板,作为 GN 模板的参数。
#include <iostream>
// This header file has been generated from the strings library fuchsia.intl.l10n.
#include "fuchsia/intl/l10n/cpp/fidl.h"
// Each library name segment between dots gets its own nested namespace in
// the generated C++ code.
using fuchsia::intl::l10n::MessageIds;
int main() {
std::cout << "Constant: " << static_cast<uint64_t>(MessageIds::STRING_NAME) << std::endl;
return 0;
}
*.json
FIDL 和 C++ 代码生成使消息 ID 可供程序使用 作者。在包装方面,我们还必须为以下资源提供本地化资源: 支持的每种语言目前,此信息的编码为 JSON。这样做是为了方便起见,但还有许多改进空间 以提高性能和安全性。
生成此信息会委托给名为
strings_to_json,
它将原始 strings.xml
与语言特定的
文件(例如,法语翻译位于 strings_fr.xml
)。
同样,对于由 GN 驱动的 build,调用 strings_to_json
封装在构建规则中
下面给出了生成的 JSON 文件的示例内容。
{
"locale_id": "fr",
"source_locale_id": "en-US",
"num_messages": 3,
"messages": {
"42": "le string",
"43": "le string 2",
"44": "le string\nwith intervening newline"
}
}
JSON 格式具有以下当前定义的字段。如果表 因此 JSON 结构的可靠来源是 字符串 模型。
字段 | 类型 | 说明 |
---|---|---|
locale_id |
语言区域 ID(字符串) | 消息翻译的语言区域。 |
source_locale_id |
语言区域 ID(字符串) | 来源消息文件的语言区域。 |
num_messages |
正整数 | 原始 strings.xml 中存在的消息数量。这样,我们就可以将消息数量与 JSON 文件中存在的消息数量进行比较,从而快速估算翻译质量。 |
messages |
地图:[u64->string] |
从消息 ID 到相应消息的映射。 |