Json 修改现有yaml文件并添加新数据和注释
我最近看到go库有了新版本(V3) 有了这些功能(我认为这是一个致命的特性:)),它可以帮助修改YAML,而不改变文件的结构 但是由于它是相当新的(从上周开始),我没有找到一些有用的文档和我需要的上下文的示例(添加新的对象/节点,保持文件结构不变,而不删除注释等) 我需要的是操作yaml文件 比如说 我有这个山药档案Json 修改现有yaml文件并添加新数据和注释,json,go,yaml,abstract-syntax-tree,Json,Go,Yaml,Abstract Syntax Tree,我最近看到go库有了新版本(V3) 有了这些功能(我认为这是一个致命的特性:)),它可以帮助修改YAML,而不改变文件的结构 但是由于它是相当新的(从上周开始),我没有找到一些有用的文档和我需要的上下文的示例(添加新的对象/节点,保持文件结构不变,而不删除注释等) 我需要的是操作yaml文件 比如说 我有这个山药档案 version: 1 type: verbose kind : bfr # my list of applications applications: - name: app
version: 1
type: verbose
kind : bfr
# my list of applications
applications:
- name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
现在我得到了一个json对象(例如带有app2
),我需要将其插入到现有文件中
[
{
"comment: "Second app",
"name": "app2",
"kind": "golang",
"path": "app2",
"exec": {
"platforms": "dockerh",
"builder": "test"
}
}
]
我需要在第一个应用程序之后将其添加到yml文件中,(应用程序是应用程序的数组)
是否可以从yaml文件中添加新的json对象?同时删除现有的
我也找到了这个博客
这是表示对象的类型
type VTS struct {
version string `yaml:"version"`
types string `yaml:"type"`
kind string `yaml:"kind,omitempty"`
apps Applications `yaml:"applications,omitempty"`
}
type Applications []struct {
Name string `yaml:"name,omitempty"`
Kind string `yaml:"kind,omitempty"`
Path string `yaml:"path,omitempty"`
Exec struct {
Platforms string `yaml:"platforms,omitempty"`
Builder string `yaml:"builder,omitempty"`
} `yaml:"exec,omitempty"`
}
更新
在测试了wiil7200提供的解决方案后,我发现了两个问题
我最后用它来写文件
err=ioutil.WriteFile(“output.yaml”,b,0644)
yaml输出有2个问题
应用程序的数组是从注释开始的,它应该
从名字开始
在名称
条目之后,将显示种类
属性和之后的所有其他属性
未与名称对齐
你知道如何解决这些问题吗?关于注释
问题,假设我是从其他属性获得的
而不是来自json(如果它使它更简单的话)
首先,让我先说使用yaml.Node在从有效的yaml进行编组时不会生成有效的yaml,如下例所示。可能应该提出一个问题
主程序包
进口(
“fmt”
“日志”
“gopkg.in/yaml.v3”
)
变量(
sourceYaml=`版本:1
类型:详细
种类:bfr
#我的申请表
应用:
#第一个应用程序
-名称:app1
种类:nodejs
路径:app1
执行官:
平台:k8s
建造商:测试
`
)
func main(){
t:=yaml.Node{}
错误:=yaml.Unmarshal([]字节(sourceYaml),&t)
如果错误!=零{
log.Fatalf(“错误:%v”,错误)
}
b、 错误:=yaml.Marshal(&t)
如果错误!=零{
log.Fatal(错误)
}
格式打印项次(字符串(b))
}
在go版本go1.12.3 windows/amd64中生成以下无效yaml
version: 1
type: verbose
kind: bfr
# my list of applications
applications:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
其次,使用结构,例如
类型VTS结构{
版本字符串`yaml:“版本”json:“版本”`
类型字符串`yaml:“类型”json:“类型”`
种类字符串`yaml:“种类,省略空”json:“种类,省略空”`
Apps yaml.Node`yaml:“应用程序,省略空”json:“应用程序,省略空”`
}
从ubuntu的博客和源代码文档来看,它似乎可以正确识别结构中作为节点的字段,并单独构建树,但事实并非如此。
当解组时,它将给出一个正确的节点树,但当重新组时,它将生成以下yaml,其中包含yaml.node公开的所有字段。遗憾的是,我们不能走这条路,必须找到另一条路
version: "1"
type: verbose
kind: bfr
applications:
kind: 2
style: 0
tag: '!!seq'
value: ""
anchor: ""
alias: null
content:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
headcomment: ""
linecomment: ""
footcomment: ""
line: 9
column: 3
忽略结构中yaml.Nodes的第一个问题和封送错误(在gopkg.in/yaml.v3.0.0-20190409140830-cdc409dda467上),我们现在可以开始操作包公开的节点。不幸的是,没有一种抽象可以轻松地添加节点,因此使用可能会有所不同,而识别节点可能是一件痛苦的事情。反思在这里可能有点帮助,所以我把它留给你们作为练习
您将发现comment spew.Dumps以一种很好的格式转储整个节点树,这有助于在将节点添加到源树时进行调试
当然,您也可以删除节点,您只需要确定需要删除哪些特定节点。如果父节点是一个映射或序列,您只需确保删除它
主程序包
进口(
“编码/json”
“fmt”
“日志”
“gopkg.in/yaml.v3”
)
变量(
sourceYaml=`版本:1
类型:详细
种类:bfr
#我的申请表
应用:
#第一个应用程序
-名称:app1
种类:nodejs
路径:app1
执行官:
平台:k8s
建造商:测试
`
modifyJsonSource=`
[
{
“评论”:“第二个应用程序”,
“名称”:“app2”,
“善良”:“戈朗”,
“路径”:“app2”,
“执行官”:{
“平台”:“dockerh”,
“生成器”:“测试”
}
}
]
`
)
//悉尼威立雅运输公司需要公开字段,否则解组将不会填充未报告的字段。
类型VTS结构{
版本字符串`yaml:“版本”json:“版本”`
类型字符串`yaml:“类型”json:“类型”`
种类字符串`yaml:“种类,省略空”json:“种类,省略空”`
Apps Applications`yaml:“Applications,ommitempty”json:“Applications,ommitempty”`
}
类型应用程序[]结构{
名称字符串`yaml:“名称,省略空”json:“名称,省略空”`
种类字符串`yaml:“种类,省略空”json:“种类,省略空”`
路径字符串`yaml:“路径,省略空”json:“路径,省略空”`
执行结构{
平台字符串`yaml:“平台,省略空”json:“平台,省略空”`
生成器字符串`yaml:“生成器,省略空”json:“生成器,省略空”`
}`yaml:“exec,ommitempty”json:“exec,ommitempty”`
注释字符串`yaml:“注释,省略空”json:“注释,省略空”`
}
func main(){
t:=yaml.Node{}
错误:=yaml.Unmarshal([]字节(sourceYaml),&t)
如果错误!=零{
log.Fatalf(“错误:%v”,错误)
}
//查找包含项的seq数组的Map节点
applicationNode:=迭代节点(&t,“应用程序”)
//转储(iterateNode(&t,“应用程序”))
var addFromJson应用程序
err=json.Unmarshal([]字节(modifyJsonSource),&addFromJson)
如果错误!=零{
原木,肥肉
version: 1
type: verbose
kind: bfr
# my list of applications
applications:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
version: "1"
type: verbose
kind: bfr
applications:
kind: 2
style: 0
tag: '!!seq'
value: ""
anchor: ""
alias: null
content:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
headcomment: ""
linecomment: ""
footcomment: ""
line: 9
column: 3
version: 1
type: verbose
kind: bfr
# my list of applications
applications:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
- # Second app
name: app2
kind: golang
path: app2
exec:
platform: dockerh
builder: test