doujinge9648
2018-02-11 15:34 阅读 99
已采纳

从Yaml文件中删除属性

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条回答 默认 最新

  • 已采纳
    dongyulian5801 dongyulian5801 2018-02-11 17:25

    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 = ""
    }
    
    点赞 评论 复制链接分享
  • douluan5444 douluan5444 2018-02-11 17:23

    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.

    点赞 评论 复制链接分享

相关推荐