去解析yaml文件

Rog*_*ers 14 struct yaml go

我正在尝试使用Go解析yaml文件.不幸的是我无法弄清楚如何.我有的yaml文件是这样的:

---
firewall_network_rules:
  rule1:
    src:       blablabla-host
    dst:       blabla-hostname
...
Run Code Online (Sandbox Code Playgroud)

我有这个Go代码,但它不起作用:

package main

import (
    "fmt"
    "io/ioutil"
    "path/filepath"

    "gopkg.in/yaml.v2"
)

type Config struct {
    Firewall_network_rules map[string][]string
}

func main() {
    filename, _ := filepath.Abs("./fruits.yml")
    yamlFile, err := ioutil.ReadFile(filename)

    if err != nil {
        panic(err)
    }

    var config Config

    err = yaml.Unmarshal(yamlFile, &config)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Value: %#v\n", config.Firewall_network_rules)
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我收到一个错误.我认为这是因为我没有为src和dst键/值创建结构.仅供参考:当我将其更改为列表时,它可以正常工作.

所以上面的代码解析了这个:

---
firewall_network_rules:
  rule1:
    - value1
    - value2
...
Run Code Online (Sandbox Code Playgroud)

Jaz*_*Cat 12

如果您更专门地使用谷歌云或kubernetes并想要解析service.yaml,如下所示:

apiVersion: v1
kind: Service
metadata:
  name: myName
  namespace: default
  labels:
    router.deis.io/routable: "true"
  annotations:
    router.deis.io/domains: ""
spec:
  type: NodePort
  selector:
    app: myName
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443
Run Code Online (Sandbox Code Playgroud)

提供一个真实世界的例子,让你了解如何编写嵌套.

type Service struct {
    APIVersion string `yaml:"apiVersion"`
    Kind       string `yaml:"kind"`
    Metadata   struct {
        Name      string `yaml:"name"`
        Namespace string `yaml:"namespace"`
        Labels    struct {
            RouterDeisIoRoutable string `yaml:"router.deis.io/routable"`
        } `yaml:"labels"`
        Annotations struct {
            RouterDeisIoDomains string `yaml:"router.deis.io/domains"`
        } `yaml:"annotations"`
    } `yaml:"metadata"`
    Spec struct {
        Type     string `yaml:"type"`
        Selector struct {
            App string `yaml:"app"`
        } `yaml:"selector"`
        Ports []struct {
            Name       string `yaml:"name"`
            Port       int    `yaml:"port"`
            TargetPort int    `yaml:"targetPort"`
            NodePort   int    `yaml:"nodePort,omitempty"`
        } `yaml:"ports"`
    } `yaml:"spec"`
}
Run Code Online (Sandbox Code Playgroud)

有一个名为json-to-go的便捷服务https://mholt.github.io/json-to-go/将json转换为结构,只需将您的YAML转换为JSON并输入到该服务中,您将获得一个自动生成的结构.

以前的海报写道:

var service Service

err = yaml.Unmarshal(yourFile, &service)
if err != nil {
    panic(err)
}

fmt.Print(service.Metadata.Name)
Run Code Online (Sandbox Code Playgroud)


小智 8

如果您不关心规则名称,为什么不组织您的yaml文件?

---
firewall_network_rules:
  - 
    name:      rule1
    src:       blablabla-host
    dst:       blabla-hostname
  - 
    name:      rule2
    src:       bla-host
    dst:       bla-hostname
Run Code Online (Sandbox Code Playgroud)

所以代码将是这样的,它是干净和可扩展的:

type Rule struct {
    Name  string  `yaml:"name"`
    Src   string  `yaml:"src"`
    Dst   string  `yaml:"dst"`
}

type Config struct {
   FirewallNetworkRules []Rule  `yaml:"firewall_network_rules"`
}
Run Code Online (Sandbox Code Playgroud)


Rog*_*ers 7

好吧,我想我已经把它弄清楚了.以下代码可以正常工作.有什么建议/改进吗?

package main

import (
    "fmt"
    "io/ioutil"
    "path/filepath"

    "gopkg.in/yaml.v2"
)

type Config struct {
    Firewall_network_rules map[string]Options
}

type Options struct {
    Src string
    Dst string
}

func main() {
    filename, _ := filepath.Abs("./fruits.yml")
    yamlFile, err := ioutil.ReadFile(filename)

    if err != nil {
        panic(err)
    }

    var config Config

    err = yaml.Unmarshal(yamlFile, &config)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Value: %#v\n", config.Firewall_network_rules)
}
Run Code Online (Sandbox Code Playgroud)

  • 尝试使用更惯用的`FirewallNetworkRules`并添加一个struct标记以捕获YAML格式-例如`yaml:“ firewall_network_rules”``有关YAML库中struct标记用法的文档,请参见此处:http://godoc.org/ gopkg.in/yaml.v2#元帅 (2认同)