go - Yaml 文件在 Golang 中进行结构解析(翻译)

标签 go yaml

我正在尝试为我的 web 应用程序构建翻译功能。我的应用程序中有多个包。每个包(目录)都包含一个翻译文件夹和里面的 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: "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 库(https://godoc.org/gopkg.in/yaml.v2),则可以创建一个 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"`
}


这将设置 MyAbcField 的值至"my data"将 Unmarshal 与 ExampleStruct 一起使用时和以下 YAML:
abc: "my data"

这允许您设计一个匹配的 Golang 结构,但是您决定构建您的 YAML。

这是我在 Go Playground 中的上述代码:https://play.golang.org/p/Q9FvNsw-BOx

现在,如果您无法修复 YAML 文件的结构,您也可以解析为嵌套映射。您可以通过传递 interface{} 类型的变量来完成此操作。 (空接口(interface))到 Unmarshal 而不是结构。但是,这需要大量样板文件,因为您需要执行类型断言才能访问您的数据。因此,除非您绝对无法避免,否则我建议使用固定结构。

这是一个示例,我解析您发布的 YAML,然后获取 msgLogin field :
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"])

这是我的结构示例的 Go Playground,改为使用解析为嵌套 map :https://play.golang.org/p/ERBjClSazkz

关于go - Yaml 文件在 Golang 中进行结构解析(翻译),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61514438/

相关文章:

macos - Golang 1.6.2 不会在 OSX Sierra 上升级

xml - 使用 Go 解析 XML,具有多个小写元素

带有外部和嵌入式 yaml 的 RMarkdown

python - 在 Python 中访问 YAML 数据

java - Spring条件yaml属性值

android - Flutter本地化和sdk可能不兼容

java - spring boot 使用环境加载 yml 来映射

amazon-web-services - k8s controller watch other controller CR

linux - Qemu-ARM 用户仿真。使用 Go 时出错

file - 如何获取具有特定扩展名的所有文件的路径