php Xiaobian Xigua today introduces you to a very useful technique - unmarshalling YAML into a dictionary and mapping keys to structural attributes. YAML is a lightweight data serialization format commonly used for configuration files and data exchange. By unmarshalling YAML, we can convert it into a dictionary, and then map the dictionary keys to structural properties, making it easier for us to perform further operations and processing in the code. This technique is very useful when dealing with configuration files or loading data from external data sources. Let's take a look at the specific implementation method!
I did search here for a while but did not find a suitable answer:
I'm trying to unmarshal yaml dict keys onto attributes of a struct rather than mapped keys. Given this yaml
commands: php: service: php bin: /bin/php node: service: node bin: /bin/node
I was able to unmarshal it into a structure like this:
type config struct { commands map[string]struct { service string bin string } }
But how can I unpack it into a structure like this:
type Config struct { Commands []struct { Name string // <-- this should be key from the yaml (i.e. php or node) Service string Bin string } }
Thanks in advance for your help
You can write a custom unmarshaller like this (on the go playground):
package main import ( "fmt" "gopkg.in/yaml.v3" ) var input []byte = []byte(` commands: php: service: php bin: /bin/php node: service: node bin: /bin/node `) type Command struct { Service string Bin string } type NamedCommand struct { Command Name string } type NamedCommands []NamedCommand type Config struct { Commands NamedCommands } func (p *NamedCommands) UnmarshalYAML(value *yaml.Node) error { if value.Kind != yaml.MappingNode { return fmt.Errorf("`commands` must contain YAML mapping, has %v", value.Kind) } *p = make([]NamedCommand, len(value.Content)/2) for i := 0; i < len(value.Content); i += 2 { var res = &(*p)[i/2] if err := value.Content[i].Decode(&res.Name); err != nil { return err } if err := value.Content[i+1].Decode(&res.Command); err != nil { return err } } return nil } func main() { var f Config var err error if err = yaml.Unmarshal(input, &f); err != nil { panic(err) } for _, cmd := range f.Commands { fmt.Printf("%+v\n", cmd) } }
I've split the command data into command
and namedcommand
to make the code simpler since you can just call decode
to provide the embedded command
The value of the structure. If everything is in the same struct, you'll need to manually map keys to struct fields.
The above is the detailed content of Unmarshal yaml mapping dict keys to structure properties. For more information, please follow other related articles on the PHP Chinese website!