php editor Youzi mentioned an important concept when introducing YAML, which is to use multiple complex mapping keys as a structure. YAML is a format used to represent data serialization and is highly human-readable. In YAML, you can use structures to combine multiple key-value pairs into a whole, making the structure of the data clearer and easier to understand. This approach can help developers better organize and manage complex data and improve code readability and maintainability. In practical applications, structures are a very useful feature, let's take a look at it!
I want to unmarshal a complex map key into a structure:
yaml
unf: item_meta: source: ? id: "aa" name: "bb" : "some value"
structure
type source struct { id string `yaml:"id"` name string `yaml:"name"` }
Everything works as expected until I add another key:
yaml 2
unf: item_meta: source: ? id: "012" name: "bill" : "some value" ? id: "066" name: "bob" : "another value"
I received an error
"line xxx: mapping key "" already defined at line xxx"
I decided to use an alias:
yaml 3
unf: item_meta: aliases: - bill: &alias_bill id: "012" name: "Bill" - bob: &alias_bob id: "066" name: "Bob" source: ? *alias_bill : "some value" ? *alias_bob name: "Bob" : "another value"
The problem is solved! But we are using hiera server
in the stack and hiera
returns the contents of the replaced config file, so I end up with yaml 2 version. p>
Any ideas on how to solve this problem? Unable to configure hiera server
.
Go to the playground
My solution is mainly based on this problem @larsks
The idea is to find nodes with duplicate map keys and create custom values from the mapped node's value node.
func fixYamlNode(node *yaml.Node) { if node.Kind == yaml.MappingNode { length := len(node.Content) for i := 0; i < length; i += 2 { nodes := make([]*yaml.Node, 0) nodes = append(nodes, node.Content[i]) for j := i + 2; j < length; j += 2 { nj := node.Content[j] if nodes[0].Kind == nj.Kind && nodes[0].Value == nj.Value { nodes = append(nodes, nj) } } if len(nodes) == 1 { continue } fillMapValue(nodes) } for i := 1; i < length; i += 2 { valueNode := node.Content[i] fixYamlNode(valueNode) } } } func fillMapValue(nodes []*yaml.Node) { for _, node := range nodes { length := len(node.Content) for i := 0; i < length; i += 2 { node.Value = fmt.Sprintf("%s %s", node.Value, node.Content[i+1].Value) } } }
The above is the detailed content of yaml uses multiple complex mapping keys as a structure. For more information, please follow other related articles on the PHP Chinese website!