如何在Golang中使用动态键解析YAML

我正在尝试使用Go解析YAML文件。问题在于YAML文件中的密钥可能并不总是相同。这是为了进行API版本控制,以便用户可以定义他们支持的版本。例如V1,V2,V3等。它们不需要按顺序排列,并且可以省略它们不支持的版本,例如V0,V2,V5等。

package main

import (

"fmt"

"gopkg.in/yaml.v2"

)

var data = `

---

development:

skip-header-validation: true

V1:

current: "1.0.0"

mime_types:

- application/vnd.company.jk.identity+json;

- application/vnd.company.jk.user+json;

- application/vnd.company.jk.role+json;

- application/vnd.company.jk.scope+json;

- application/vnd.company.jk.test+json;

skip-mime-type-validation: true

skip-version-validation: true

V2:

current: "2.0.0"

mime_types:

- application/vnd.company.jk.identity+json;

- application/vnd.company.jk.user+json;

- application/vnd.company.jk.role+json;

- application/vnd.company.jk.scope+json;

- application/vnd.company.jk.test+json;

`

type MajorVersion struct {

Current string `yaml:"current"`

MimeTypes []string `yaml:"mime_types"`

SkipVersionValidation bool `yaml:"skip-version-validation"`

SkipMimeTypeValidation bool `yaml:"skip-mime-type-validation"`

}

type Environment struct {

SkipHeaderValidation bool `yaml:"skip-header-validation"`

Version map[string]MajorVersion

}

func main() {

e := Environment{}

yaml.Unmarshal([]byte(data), &e)

fmt.Println(e)

}

这是最高层,我还没有从结构内部弄清楚如何做到这一点。

回答:

首先,您尝试将根解析为Environment,但其实际类型为map[string]Environment。其次,Unmarshaler如果要保留该类型结构,则需要一个自定义项。像这样:

package main

import (

"fmt"

"gopkg.in/yaml.v2"

)

var data = `

---

development:

skip-header-validation: true

V1:

current: "1.0.0"

mime_types:

- application/vnd.company.jk.identity+json;

- application/vnd.company.jk.user+json;

- application/vnd.company.jk.role+json;

- application/vnd.company.jk.scope+json;

- application/vnd.company.jk.test+json;

skip-mime-type-validation: true

skip-version-validation: true

V2:

current: "2.0.0"

mime_types:

- application/vnd.company.jk.identity+json;

- application/vnd.company.jk.user+json;

- application/vnd.company.jk.role+json;

- application/vnd.company.jk.scope+json;

- application/vnd.company.jk.test+json;

`

type MajorVersion struct {

Current string `yaml:"current"`

MimeTypes []string `yaml:"mime_types"`

SkipVersionValidation bool `yaml:"skip-version-validation"`

SkipMimeTypeValidation bool `yaml:"skip-mime-type-validation"`

}

type Environment struct {

SkipHeaderValidation bool

Versions map[string]MajorVersion

}

func (e *Environment) UnmarshalYAML(unmarshal func(interface{}) error) error {

var params struct {

SkipHeaderValidation bool `yaml:"skip-header-validation"`

}

if err := unmarshal(&params); err != nil {

return err

}

var versions map[string]MajorVersion

if err := unmarshal(&versions); err != nil {

// Here we expect an error because a boolean cannot be converted to a

// a MajorVersion

if _, ok := err.(*yaml.TypeError); !ok {

return err

}

}

e.SkipHeaderValidation = params.SkipHeaderValidation

e.Versions = versions

return nil

}

func main() {

var e map[string]Environment

if err := yaml.Unmarshal([]byte(data), &e); err != nil {

fmt.Println(err.Error())

}

fmt.Printf("%#v\n", e)

}

输出(使用化妆后):

map[string]main.Environment{

"development": {

SkipHeaderValidation: true,

Versions: {

"V2": {

Current: "2.0.0",

MimeTypes: {"application/vnd.company.jk.identity+json;", "application/vnd.company.jk.user+json;", "application/vnd.company.jk.role+json;", "application/vnd.company.jk.scope+json;", "application/vnd.company.jk.test+json;"},

SkipVersionValidation: false,

SkipMimeTypeValidation: false,

},

"V1": {

Current: "1.0.0",

MimeTypes: {"application/vnd.company.jk.identity+json;", "application/vnd.company.jk.user+json;", "application/vnd.company.jk.role+json;", "application/vnd.company.jk.scope+json;", "application/vnd.company.jk.test+json;"},

SkipVersionValidation: true,

SkipMimeTypeValidation: true,

},

},

},

}

以上是 如何在Golang中使用动态键解析YAML 的全部内容, 来源链接: utcz.com/qa/433736.html

回到顶部