Home > Software design >  Get a value from a known key in a dynamic nested YAML
Get a value from a known key in a dynamic nested YAML

Time:01-31

I'm pretty new to Golang. I have a YAML file with dynamic keys but only one is known, and it's not necessarily the first one (after config). There is no other key at the level of config.

The yaml file :

config:
    foo:bar: baz
    bar:foo: baz
    abs:getit: myvalue

I want to retrieve myvalue from the nested key config:abs:getit. This nested key name will never change, it will always be config:abs:getit. All other keys can be whatever, we don't care, with different types of content (arrays, int, strings, array of array).

What is the best way to recover the value ?

I worked with yaml package, but I have to fix every field in a struct to unmarshall it, but I don't know how many nested keys there can be so I cannot write a struct which works all the time.

I worked with a map, but I can figure out which map I have to use, because if I can have a field with 6 nested keys or 3 nested keys with array in it before the value I'm searching and it will fails.

I am pretty lost with those kind of things in a dynamic context.

Ideally, I want to do a cat myFile.yaml | yq '.config."abs:getit"', but in Golang...

Any ideas and best practices to do that ?

CodePudding user response:

You can do:

func main() {
    var obj struct {
        Config struct {
            AbsGetit string `yaml:"abs:getit"`
        } `yaml:"config"`
    }
    err := yaml.Unmarshal(data, &obj)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%q\n", obj.Config.AbsGetit)
}

https://go.dev/play/p/KJ_lzZxaZBy

CodePudding user response:

Thank you for your precise answer. I'm sorry but there is an error in the question, and I apologize for the mistake.

It's not a single flow scalar Yaml but a map, since there is space before the value :

config:
    foo:bar: baz
    bar:foo: baz
    abs:getit: myvalue

The code above logically returns a conversion error like this :

panic: yaml: unmarshal errors:
  line 2: cannot unmarshal !!map into string

My whole code is here. The file I read is a Pulumi config Yaml, which will be different for all projects, except for one common key ("abs:getit:"), only the value is different.

The original question file has been modified. Really sorry for that...

  • Related