【问题标题】:Parse yaml file to predefined struct in go将 yaml 文件解析为 go 中的预定义结构
【发布时间】:2018-05-24 19:23:15
【问题描述】:

我有多个 yaml 文件需要解析并且结构完全相同

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

模式部分对于应用程序应该使用的所有 yaml 都是必需的 永远得到

依赖标签可以包含 1..n 个带有必填字段的条目 ,名称,类型, cwd

依赖标签可以(或不)包含install部分和nameproperties 这是强制性的

依赖标签可以(或不)包含provides 部分和name 这是强制性的

安装可以有属性,提供也可以有 属性

我正在使用yaml parser 来解析文件,但我的问题是如何在 Golang 中构建结构,当我解析文档时,它将自动填充主结构并包含子结构(例如依赖项/安装部分)

我尝试过类似的东西

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

    dependency struct {
        name  string
        type string
        cwd string

    install struct {
        name  string
    }


}

在安装部分,它可以是组或类型或两者兼而有之,它也可以有属性部分,所以我不知道如何构建 我用来解析文档的一些通用/可扩展结构(文档具有关闭的属性列表,我在示例中描述的选项最多)

我使用这个库来解析文档

yaml parser

【问题讨论】:

    标签: go struct yaml


    【解决方案1】:

    你的结构定义应该是这样的

    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
    }
    

    这里是完整的示例代码:

    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\n", y)
    
    }
    

    输出

    {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}}]}]}
    

    如果你想从 yaml 文件中读取,在 main func 中只需替换:

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

    yamlFile, err := ioutil.ReadFile("yaml_sample.yaml")
    if err != nil {
        log.Printf("yamlFile.Get err   #%v ", err)
    }
    err = yaml.Unmarshal(yamlFile, &y)
    

    【讨论】:

    • 谢谢 1+,您能否提供示例,您将如何解析该结构的答案中的文件?
    • 非常感谢,我已经尝试了您的示例,它可以部分工作 install properties provides 对象是空的,知道吗?
    • 对不起,没关系,问题出在 vs 代码调试器上,它似乎没有在深层结构中显示对象...查看我的更新,您无法打开数组对象以查看其中的内容跨度>
    • 我的最后一个问题 :) 如果您需要构建这个 golang 程序,您将如何构建项目,假设主要位于 rootProj-> cmd>main.go 下,您将所有“结构”放在哪里(哪个文件夹在proj 以及是否为每个结构创建新文件 ...) 以及如何将它们加载到 main 方法。非常感谢!
    • 如果应用程序就是这个问题描述中的全部内容,您可以将其全部保存在一个文件中。您的应用程序的最终设计应取决于您的全部要求和复杂性。这感觉像是另一个问题,而且太笼统了。您能否将其与另一个 StackOverflow 问题分开并提供更多细节。
    猜你喜欢
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 2017-01-04
    相关资源
    最近更新 更多