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

在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)
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题