Parsing YAML with Dynamic Key in Go
This problem arises when parsing YAML files with keys that can vary depending on the user's defined API versions. The user may omit or arrange versions as needed (e.g., V0, V2, V5).
Original Approach with Environment Structure
The initial approach involves parsing the YAML as an Environment struct. However, the actual type of the parsed data is map[string]Environment.
<code class="go">type Environment struct { SkipHeaderValidation bool `yaml:"skip-header-validation"` Version map[string]MajorVersion }</code>
To resolve this, we need a custom Unmarshaler.
Custom Unmarshaler for Environment
We create a custom Unmarshaler method for the Environment type that parses both the static and dynamic keys.
<code class="go">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 { // Expect error here due to boolean to MajorVersion conversion if _, ok := err.(*yaml.TypeError); !ok { return err } } e.SkipHeaderValidation = params.SkipHeaderValidation e.Versions = versions return nil }</code>
Modified Parsing and Output
We can now modify our parsing code to handle the dynamic keys and ultimately return the desired data structure.
Modified Main Function
<code class="go">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) }</code>
Output
The output will now reflect the expected data structure with the dynamic keys parsed accordingly.
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, }, }, }, }
The above is the detailed content of How to Parse YAML with Dynamic Keys in Go Using a Custom Unmarshaler?. For more information, please follow other related articles on the PHP Chinese website!