我正在尝试使用Go解析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
...
答案 0 :(得分:9)
如果你更专门地使用谷歌云或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-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)
答案 1 :(得分: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)
}
答案 2 :(得分:7)
如果您不关心规则名称,为什么不整理下面的yaml文件?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static int N = 5;
static void* run(void *arg) {
int *i = (int *) arg;
char buf[123];
snprintf(buf, sizeof(buf), "thread %d", *i);
return buf;
}
int main(int argc, char *argv[]) {
int i;
pthread_t *pt = NULL;
for (i = 0; i < N; i++) {
pthread_create(pt, NULL, run, &i);
}
return EXIT_SUCCESS;
}
因此代码将是这样的,它是干净且可扩展的:
---
firewall_network_rules:
-
name: rule1
src: blablabla-host
dst: blabla-hostname
-
name: rule2
src: bla-host
dst: bla-hostname
答案 3 :(得分:1)
如果您的YAML文件很简单(单一嵌套),如下所示
main(){
config := Config()
mongoConfig := config["mongo"]
mongo.MongoDial(
String(
Get(mongoConfig, "DB")
),
String(
Get(mongoConfig, "COL")
)
)
}
func Config() map[string]interface{} {
filename, _ := filepath.Abs("configs/config.yaml")
yamlFile, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
var config map[string]interface{}
err = yaml.Unmarshal(yamlFile, &config)
if err != nil {
panic(err)
}
return config
}
func Get(this interface{}, key string) interface{} {
return this.(map[interface{}]interface{})[key]
}
func String(payload interface{}) string {
var load string
if pay, oh := payload.(string); oh {
load = pay
}else{
load = ""
}
return load
}
在这里,您可以使用interface而不是声明struct。
struct
这适用于1级嵌套,如果你有复杂的嵌套,那么建议使用%timeit df['Host'] + "/" + df['Protocol'] + "/" + df['Port'].map(str)
%timeit ['/'.join(i) for i in zip(df['Host'],df['Protocol'],df['Port'].map(str))]
%timeit ['/'.join(i) for i in df[['Host','Protocol','Port']].astype(str).values]
。