Golang中Yaml文件到结构解析(翻译)
我正在尝试为我的webapp构建一个翻译功能。我的应用程序中有多个软件包。每个包(目录)中都包含一个翻译文件夹和yaml文件。但我在解析和将其分配给消息时遇到问题 en.yamlGolang中Yaml文件到结构解析(翻译),go,yaml,Go,Yaml,我正在尝试为我的webapp构建一个翻译功能。我的应用程序中有多个软件包。每个包(目录)中都包含一个翻译文件夹和yaml文件。但我在解析和将其分配给消息时遇到问题 en.yaml msgLogin : "You've login successfully" msgProducts: 0: "You don't have any product." 1: "You have %d product." 2: "You have %d products." errLogin: "Wro
msgLogin : "You've login successfully"
msgProducts:
0: "You don't have any product."
1: "You have %d product."
2: "You have %d products."
errLogin: "Wrong password or username"
我的代码:
type TranslationEntry struct {
Key struct {
Value interface{}
}
}
func parseTranslations(dir string) {
files, _ := ioutil.ReadDir(dir)
for _, f := range files {
yamlFile, _ := ioutil.ReadFile(dir + "/" + f.Name())
var data translation
if err := yaml.Unmarshal(yamlFile, &data); err != nil {
return nil, err
}
lang := strings.Split(f.Name(), ".")[0]
switch msg := data.Key.Value.(type) {
case string:
message.SetString(language.Make(lang), cast.ToString(data.Key), cast.ToString(data.Key.Value))
case map[int]string:
message.Set(language.Make(lang), cast.ToString(data.Key),
plural.Selectf(1, "%d",
"=0", cast.ToString(data.Key.Value["0"]),
"=1", cast.ToString(data.Key.Value["1"]),
"=2", cast.ToString(data.Key.Value["2"]),
))
}
translations[lang] = &dictionary{Data: data}
}
}
我完全不知道如何设计我的结构或解析yaml文件
如果您使用的是YAML库,我认为您使用的是(),要制作一个Golang结构,可以使用Unmarshal从您文章中的YAML文件映射,请执行以下操作:
type TranslationEntry struct {
MsgLogin string `yaml:"msgLogin"`
MsgProducts map[int]string `yaml:"msgProducts"`
ErrLogin string `yaml:"errLogin"`
}
在字段声明之后,``中的内容称为标记。它们是在某些数据类型和Golang结构之间映射时通常指定字段名的方式(在我的例子中,通常我将结构映射到JSON,但我也完成了YAML)。如果您使用的是我上面提到的同一个YAML解析器,那么它就是这样工作的
基本上,双引号内的文本是结构字段将映射到的YAML键。在上述代码中,YAML键名称和结构字段名称之间的唯一区别是大写,但下面是一个使用完全不同名称的示例:
type ExampleStruct struct {
MyAbcField string `yaml:"abc"`
}
这将在对ExampleStruct
和以下YAML使用解组时,将MyAbcField
的值设置为“我的数据”
:
abc: "my data"
这允许您设计一个Golang结构,它与您决定构建YAML的方式相匹配
以下是我在围棋场的上述代码:
现在,如果您无法修复YAML文件的结构,还可以将其解析为嵌套映射。您可以通过将接口{}
类型的变量(空接口)传递给Unmarshal而不是结构来实现这一点。然而,这需要大量的样板文件,因为需要进行类型断言才能访问数据。因此,我建议使用固定结构,除非你绝对无法避免
下面是一个示例,我解析您发布的YAML,然后获得msgLogin
字段:
var data interface{}
if err := yaml.Unmarshal([]byte(yamlFile), &data); err != nil {
// handle error
}
// a type assertion that data is a map is needed in order to get keys or iterate
topLevel, ok := data.(map[interface{}]interface{})
if !ok {
// handle error
}
fmt.Println(topLevel["msgLogin"])
下面是我的struct示例的示例,改为使用解析到嵌套映射:谢谢您的回答。但有一个问题。您已经在结构中使用了MsgLogin MsgProducts等。这些是关键,在每个文件中都会有所不同。我怎么能这么做?啊,我的错。当你在帖子中说“翻译”时,我以为你指的是本地化。对于本地化,您将在每个文件中使用相同的密钥(我必须经常在英语和日语之间进行本地化)。在您的例子中,听起来您需要解析成嵌套的映射。给我一点时间检查一下。我在响应的底部添加了关于如何解析嵌套映射的信息。如果可以的话,我建议您尝试使用固定格式的结构(以避免样板文件),但是嵌套映射应该可以满足您的要求。