golang 中解析 yaml 格式内容可以使用 yaml.v3 库来解决。下载 go 依赖
go get -u gopkg.in/yaml.v3
1. 示例 yaml 数据
config_mail_template:
description: 验证码
one: Verification Code
other: Verification Code
config_mail_template_reset_code:
description: 重置密码
one: Reset password
other: Reset password
# 注释内容1
config_custom_tag: # 注释内容2
description: 自定义
one: Custom Tag
other: Custom Tag
#注释内容3
2. 普通解析
普通解析流程,解析到 map 对象,会失去对 key 的定义顺序
package yaml_demo
import (
"os"
"testing"
"gopkg.in/yaml.v3"
)
type Asset struct {
Description string `yaml:"description"`
One string `yaml:"one"`
Other string `yaml:"other"`
}
func TestParseNormal(t *testing.T) {
file, err := os.ReadFile("data.yaml")
if err != nil {
t.Error(err.Error())
return
}
var assets map[string]Asset
err = yaml.Unmarshal(file, &assets)
if err != nil {
t.Error(err.Error())
return
}
t.Log(len(assets))
}
3. 顺序解析 yaml 中的 key
yaml3 定义了 yaml.Node 对象
第一种方式
可以通过实现 UnmarshalYAML() 接口,来实现自定义对象的解析,并且保证解析 key 的顺序性
第二种方式
直接将 bytes 解析到 yaml.Node 中,此时 yaml.Node 就是文档对象
var node yaml.Node
yaml.Unmarshal(bytes,&node)
package yaml_demo
import (
"gopkg.in/yaml.v3"
"os"
"testing"
)
type Item struct {
Name string
Description string `yaml:"description"`
One string `yaml:"one"`
Other string `yaml:"other"`
}
type Items []Item
// UnmarshalYAML 自定义解析
func (a *Items) UnmarshalYAML(value *yaml.Node) error {
for i := 0; i < len(value.Content); i += 2 {
var item Item
if err := value.Content[i+1].Decode(&item); err != nil {
return err
}
item.Name = value.Content[i].Value
*a = append(*a, item)
}
return nil
}
func TestParseToSlice(t *testing.T) {
bytes, err := os.ReadFile("data.yaml")
if err != nil {
t.Error(err.Error())
return
}
var items Items
err = yaml.Unmarshal(bytes, &items)
if err != nil {
t.Error(err.Error())
return
}
t.Log(len(items))
}
4. 顺序解析后回写问题
yaml 中的 node 在更新完成后,回写内容时,虽然保留了注释,但是会去掉空白行
为了保证和原来的文件相同的空白行和注释内容,可以对 yaml 内容做如下处理
// 加载 yaml 文件,将空白行使用占位符替换
func loadYamlNode(file string) (*yaml.Node, error) {
dataBytes, err := os.ReadFile(file)
if err != nil {
return nil, err
}
buffer := bytes.NewBuffer(dataBytes)
storeBytes := make([]byte, 0, 2*buffer.Len())
storeBuffer := bytes.NewBuffer(storeBytes)
for {
line, err := buffer.ReadString('n')
if err != nil && err == io.EOF {
break
}
if line != "n" {
storeBuffer.WriteString(line)
} else {
storeBuffer.WriteString("#placeholdn")
}
}
var dataNode yaml.Node
err = yaml.Unmarshal(storeBuffer.Bytes(), &dataNode)
if err != nil {
return nil, err
}
return &dataNode, nil
}
// 回写更新内容,将占位符使用空白行替换
func saveUpdatedContent(docNode *yaml.Node, file string) error {
var bytesData []byte
buffer := bytes.NewBuffer(bytesData)
encoder := yaml.NewEncoder(buffer)
encoder.SetIndent(2)
err := encoder.Encode(docNode)
if err != nil {
return err
}
store := make([]byte, 0, buffer.Len())
storeBuffer := bytes.NewBuffer(store)
for {
line, err := buffer.ReadString('n')
if err != nil && err == io.EOF {
break
}
if line == "#placeholdn" {
storeBuffer.WriteString("n")
} else {
storeBuffer.WriteString(line)
}
}
err = os.WriteFile(file, storeBuffer.Bytes(), 0666)
return err
}
原文地址:https://blog.csdn.net/tianwenxue/article/details/130789746
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_11091.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。