Remove property from yaml file

3.5k views Asked by At

I need to read yaml file and change some properties value and write it back to the FS.

The file content is like this

ID: mytest
mod:
- name: user
  type: dev
  parameters:
    size: 256M
  build:
    builder: mybuild


type OBJ struct {
    Id            string      `yaml:"ID"`
    Mod           []*Mod   `yaml:"mod,omitempty"`
}


type Mod struct {
    Name       string
    Type       string
    Parameters       Parameters `yaml:"parameters,omitempty"`
    Build            Parameters `yaml:"build,omitempty"`

}

I need to omit the type property from the output

ID: mytest
mod:
- name: user
  parameters:
    size: 256M
  build:
    builder: mybuild

The problem is that, I can read it, I can change the property value but can not delete the key (which is type)

The code I use

yamlFile, err := ioutil.ReadFile("test.yaml")

//Here I parse the file to the model I’ve which is working fine
err := yaml.Unmarshal([]byte(yamlFile), &obj)
if err != nil {
    log.Printf("Yaml file is not valid, Error: " + err.Error())
    os.Exit(-1)
}

Now I was able to loop on the properties like

obj := models.OBJ{}


for i, element := range obj.Mod {

//Here I was able to change property data

mta.Mod[i].Name = "test123"

But not sure how I can omit the whole property of type when writing back to the FS.

I use this OS: https://github.com/go-yaml/yaml/tree/v2

2

There are 2 answers

0
Shahriar On BEST ANSWER

If you want to omit type from your whole YAML, you can Marshal your data into an object where type is not more exists

type OBJ struct {
    Id  string `yaml:"ID"`
    Mod []*Mod `yaml:"mod,omitempty"`
}

type Mod struct {
    Name        string
    //Type      string `yaml:"type"`
    Parameters  Parameters `yaml:"parameters,omitempty"`
    Build       Parameters `yaml:"build,omitempty"`
}

type will be removed, if you Marshal your data into this object.

Another solution if you do not want to use multiple object.

Use omitempty in Type. So when value of Type is "", it will be ignored

type Mod struct {
    Name       string
    Type       string `yaml:"type,omitempty"`
    Parameters  Parameters `yaml:"parameters,omitempty"`
    Build       Parameters `yaml:"build,omitempty"`
}

And do this

for i, _ := range obj.Mod {
    obj.Mod[i].Type = ""
}
0
leninhasda On

You just need to add this:

type Mod struct {
    Name       string     `yaml:"name"`
    Type       string     `yaml:"type,omitempty"` // note the omitempty
    Parameters Parameters `yaml:"parameters,omitempty"`
    Build      Parameters `yaml:"build,omitempty"`
}

Now if you do this (inside loop if you like):

obj.Mod[0].Type = "" // set to nil value of string
byt, _ := yaml.Marshal(obj)

And write the byt to file, the type will be removed.

The point is any struct field that has a omitempty tag, when marshalling with yaml.Marshal it will omit (remove) the field if it is empty (aka has nil value).

More info in official documentation.