2015-02-23 151 views
7

我想用Go解析yaml文件。不幸的是我无法弄清楚如何。 YAML的文件,我是这样的:去解析yaml文件

--- 
firewall_network_rules: 
    rule1: 
    src:  blablabla-host 
    dst:  blabla-hostname 
... 

我有这样的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) 
} 

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

所以上面的代码解析此:

--- 
firewall_network_rules: 
    rule1: 
    - value1 
    - value2 
... 

回答

5

嗯,我想我已经通过我自己琢磨出来。以下代码可以正常工作。任何建议/改进?

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) 
} 
+1

尝试更地道'FirewallNetworkRules'并添加标签结构捕捉YAML格式 - 例如''yaml:“firewall_network_rules”'' 请参阅这里了解YAML库中结构标签使用情况的文档:http://godoc.org/gopkg.in/yaml.v2#Marshal – elithrar 2015-02-23 23:51:42

+0

感谢您的建议,它确实澄清我的代码。 – 2015-02-24 08:01:10

3

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

--- 
firewall_network_rules: 
    - 
    name:  rule1 
    src:  blablabla-host 
    dst:  blabla-hostname 
    - 
    name:  rule2 
    src:  bla-host 
    dst:  bla-hostname 

因此,代码会是这样的,它是干净的,可扩展的:

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

type Config struct { 
    FirewallNetworkRules []Rule `yaml:"firewall_network_rules"` 
} 
4

如果你使用谷歌云或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 

提供一个真实世界的例子,以便您了解如何编写嵌套。

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"` 
} 

有称为便捷的服务JSON-到去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)