doulai1910 2017-12-11 09:46
浏览 89
已采纳

在Go中将yaml文件解析为预定义的结构

I’ve multiple yaml files which need to be parsed and have exactly the same structure

schema: "1.0.0"
id: test
version: "1.2.3"


dependency :
  - name: ui
    type: runner
    cwd: /ui
    install:
       - name: api
         group: test
         properties:
             name: app
             url: appUrl

  - name: backend
    type: mongoDb
    path: be
    install:
       - name: db
         type: mongo
    provides:
       - name: api
         properties:
            url: url

The schema section is mandatory for all the yaml which the app should get always

The dependency tag can contain 1..n entries with mandatory fields ,name, type, cwd

The dependency tag can (or not) contain install section with name and properties which is mandatory

The dependency tag can (or not) contain provides section with name and which is mandatory

The install can have properties and the provides also can have properties

I am using a yaml parser to parse the files but my question is how in Golang I can build struct that when I parse the doc it will automatically fill the main struct and will include the sub structs (such as dependency/ install sections )

I have tried something like

type main struct {
    schema struct {
        schema  string
        id int
        version string
    }

    dependency struct {
        name  string
        type string
        cwd string

    install struct {
        name  string
    }


}

In the install section, it can be group or type or both and it can have also properties section, so I'm not sure how to build some generic /extendable struct which I use to parse the document (the document have close list of properties, what I put in the example describe the most options)

I use this lib to parse the doc

yaml parser

enter image description here

  • 写回答

1条回答 默认 最新

  • dongzhan8001 2017-12-11 10:37
    关注

    Your struct definition should be something like this

    type Yaml struct {
        Schema     string
        ID         string
        Version    string
        Dependency []Dependency
    }
    
    type Dependency struct {
        Name     string
        Type     string
        CWD      string
        Install  []Install
        Provides []Provide
    }
    
    type Install struct {
        Name       string
        Group      string
        Type       string
        Properties Properties
    }
    
    type Properties struct {
        Name string
        URL  string
    }
    
    type Provide struct {
        Name       string
        Properties Properties
    }
    

    Here is full sample code:

    package main
    
    import (
        "fmt"
        "io/ioutil"
        "log"
    
        "gopkg.in/yaml.v2"
    )
    
    var data = `
    schema: "1.0.0"
    id: test
    version: "1.2.3"
    
    
    dependency :
      - name: ui
        type: runner
        cwd: /ui
        install:
           - name: api
             group: test
             properties:
                 name: app
                 url: appUrl
    
      - name: backend
        type: mongoDb
        path: be
        install:
           - name: db
             type: mongo
        provides:
           - name: api
             properties:
                 url: url
    `
    
    type Yaml struct {
        Schema     string
        ID         string
        Version    string
        Dependency []Dependency
    }
    
    type Dependency struct {
        Name     string
        Type     string
        CWD      string
        Install  []Install
        Provides []Provide
    }
    
    type Install struct {
        Name       string
        Group      string
        Type       string
        Properties Properties
    }
    
    type Properties struct {
        Name string
        URL  string
    }
    
    type Provide struct {
        Name       string
        Properties Properties
    }
    
    func main() {
        y := Yaml{}
    
        err := yaml.Unmarshal([]byte(data), &y)
        if err != nil {
            log.Fatalf("error: %v", err)
        }
        fmt.Printf("%+v
    ", y)
    
    }
    

    Output

    {Schema:1.0.0 ID:test Version:1.2.3 Dependency:[{Name:ui Type:runner CWD:/ui Install:[{Name:api Group:test Type: Properties:{Name:appURL:appUrl}}] Provides:[]} {Name:backend Type:mongoDb CWD: Install:[{Name:db Group: Type:mongo Properties:{Name: URL:}}] Provides:[{Name:api Properties:{Name: URL:url}}]}]}
    

    If you want to read from a yaml file, in the main func just replace:

    err := yaml.Unmarshal([]byte(data), &y)
    

    with

    yamlFile, err := ioutil.ReadFile("yaml_sample.yaml")
    if err != nil {
        log.Printf("yamlFile.Get err   #%v ", err)
    }
    err = yaml.Unmarshal(yamlFile, &y)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分