dongsuo0517 2017-12-20 13:10
浏览 185
已采纳

解析Yaml以使用动态字段进行结构化

I use the following code to parse yaml to struct which works okay. Now let's assume that I have a struct like install which I know to have two const properties like Name and Group but in addition we can have additional key val properties which could change, you can get any key val properties (dynamic)

How should I define this struct? the idea is to read the yaml file modify some values and write it back (with exact same structure with modified value) to FS, therefore I don't want to miss some dynamically fields which could be in the some yaml file which need to be modified

package main

import (
    "fmt"
    "log"

    "github.com/go-yaml/yaml"
)

type File struct {
    TypeVersion string `yaml:"_type-version"`
    Dependency []Dependency
}

type Dependency struct {
    Name     string
    Type     string
    CWD      string
    Install  []Install
    Requires []Requires
}

type Install struct {
    Name  string
    Group string
   //Here any key value can be
}

type Requires struct {
    Name string
    Type string
}

var data = `
_type-version: "1.0.0"
dependency:
  - name: ui
    type: runner
    cwd: /ui
    install:
       - name: api
         group: test
    requires:
      - name: db
      - type: mongo
      - name: rst
      - name: test
      - name: test2
`

func main() {
    f := File{}

    err := yaml.Unmarshal([]byte(data), &f)
    if err != nil {
        log.Fatalf("error: %v", err)
    }
    fmt.Printf("--- t:
%v

", f)

    d, err := yaml.Marshal(&f)
    if err != nil {
        log.Fatalf("error: %v", err)
    }
    fmt.Printf("--- t dump:
%s

", string(d))
}

Example Install can be like above and also like this

    install:
       - name: api
         group: test
         a1:test2
         b1:test2

And also

   install:
           - name: api
             group: test
             z10:123
             zzz:111

And many more fields after name and group

  • 写回答

1条回答 默认 最新

  • douken7402 2017-12-20 14:06
    关注

    Map instead of a struct for Install will help to solve the problem.

    import (
        "fmt"
        "log"
    
        "github.com/go-yaml/yaml"
    )
    
    type File struct {
        TypeVersion string `yaml:"_type-version"`
        Dependency  []Dependency
    }
    
    type Dependency struct {
        Name     string
        Type     string
        CWD      string
        Install  []Install
        Requires []Requires
    }
    
    type Install map[string]string
    
    func (i Install) name() string {
        return i["name"]
    }
    
    func (i Install) group() string {
        return i["group"]
    }
    
    type Requires struct {
        Name string
        Type string
    }
    
    var data = `
    _type-version: "1.0.0"
    dependency:
      - name: ui
        type: runner
        cwd: /ui
        install:
           - name: api
             group: test
        requires:
          - name: db
          - type: mongo
          - name: rst
          - name: test
          - name: test2
    `
    
    func main() {
        f := File{}
    
        err := yaml.Unmarshal([]byte(data), &f)
        if err != nil {
            log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t:
    %v
    
    ", f)
    
        d, err := yaml.Marshal(&f)
        if err != nil {
            log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t dump:
    %s
    
    ", string(d))
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!