Go解析yaml和yml文件

2023-11-09

Go解析yaml和yml文件


1、yaml概述

yaml一般作为配置文件的语言,类似json、xml等,但和Windows中init配置文件的功能较为相似,但更好理解,我第一次接触是在clash软件中,通过yaml文件导入相关网络数据。

以下来自维基百科的基础介绍:

YAML(/ˈjæməl/,尾音类似camel骆驼)是一个可读性高,用来表达资料序列化的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML、电子邮件的数据格式(RFC 2822)中获得灵感。Clark Evans在2001年首次发表了这种语言[1],另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者[2]。目前已经有数种编程语言或脚本语言支持(或者说解析)这种语言。

YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)[3],但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。(这让我想起了Linux is not Unix)

2、功能

YAML的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等资料形态。[4]它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。尽管它比较适合用来表达层次结构式(hierarchical model)的数据结构,不过也有精致的语法可以表示关系性(relational model)的资料。[5]由于YAML使用空白字符和分行来分隔资料,使得它特别适合用grep/Python/Perl/Ruby操作。其让人最容易上手的特色是巧妙避开各种封闭符号,如:引号、各种括号等,这些符号在嵌套结构时会变得复杂而难以辨认。

3、示例

简单的文件:

---
receipt:     Oz-Ware Purchase Invoice
date:        2012-08-06
customer:
    given:   Dorothy
    family:  Gale
   
items:
    - part_no:   A4786
      descrip:   Water Bucket (Filled)
      price:     1.47
      quantity:  4

    - part_no:   E1628
      descrip:   High Heeled "Ruby" Slippers
      size:      8
      price:     133.7
      quantity:  1

bill-to:  &id001
    street: | 
            123 Tornado Alley
            Suite 16
    city:   East Centerville
    state:  KS

ship-to:  *id001   

specialDelivery:  >
    Follow the Yellow Brick
    Road to the Emerald City.
    Pay no attention to the
    man behind the curtain.
...

注意在YAML中,字符串不一定要用双引号标示。另外,在缩进中空白字符的数目并不是非常重要,只要相同层次结构的元素左侧对齐就可以了(不过不能使用TAB字符)。这个文件的顶层由七个键值组成:其中一个键值"items",是两个元素构成的数组(或称清单),这清单中的两个元素同时也是包含了四个键值的散列表。文件中重复的部分用这个方法处理:使用锚点(&)和引用(*)标签将"bill-to"散列表的内容复制到"ship-to"散列表。也可以在文件中加入选择性的空行,以增加可读性。在一个文件中,可同时包含多个文件,并用"—“分隔。选择性的符号”…"可以用来表示文件结尾(在利用流的通信中,这非常有用,可以在不关闭流的情况下,发送结束信号)。

4、语言的构成元素

YAML提供缩进/区块以及内置(inline)两种格式,来表示清单和散列表。以下展示几种YAML的基本原件。

(1)、清单(数组)

习惯上清单比较常用区块格式(block format)表示,也就是用短杠+空白字符作为起始。

 --- # 最喜愛的電影
 - Casablanca
 - North by Northwest
 - Notorious

另外还有一种内置格式(inline format)可以选择──用方括号围住,并用逗号+空白区隔(类似JSON的语法)。

 --- # 購物清單 
 [milk, pumpkin pie, eggs, juice]

(2)、关系数组

键值和资料由冒号及空白字符分开。区块形式(常使用于YAML数据文档中)使用缩进和换行符分隔key: value对。内置形式(常使用于YAML数据流中)在大括号中使用逗号+空白字符分隔key: value对。

 --- # 區塊形式
   name: John Smith
   age: 33
 --- # 內置形式
 {name: John Smith, age: 33}

(3)、区块的字符

再次强调,字符串不需要包在引号之内。

有两种语法可以书写多行文字(multi-line strings),一种为保留换行(使用|字符),另一种为折叠换行(使用>字符)。两种语法在其特殊字符之后都必须接着换行。

(4)、保留换行(Newlines preserved)

data: |                                     # 譯者注:這是一首著名的五行民謠(limerick)
   There once was a man from Darjeeling     # 這裡曾有一個人來自大吉嶺
   Who got on a bus bound for Ealing        # 他搭上一班往伊靈的公車
       It said on the door                  # 門上這麼說的
       "Please don't spit on the floor"     # "請勿在地上吐痰"
   So he carefully spat on the ceiling      # 所以他小心翼翼的吐在天花板上

根据默认,每行开头的缩进(以首行为基准)和行末空白会被去除,而不同的缩进会保留差异。

(5)、折叠换行(Newlines folded)


data: >
   Wrapped text         # 摺疊的文字
   will be folded       # 將會被收
   into a single        # 進單一一個
   paragraph            # 段落
   
   Blank lines denote   # 空白的行代表
   paragraph breaks     # 段落之間的區隔

和保留换行不同的是,只有空白行才视为换行,原本的换行字符会被转换成空白字符,而行首缩进会被去除。

(6)、层次结构化的元素

于清单中使用散列表

- {name: John Smith, age: 33}
- name: Mary Smith
  age: 27

于散列表中使用清单

men: [John Smith, Bill Jones]
women:
  - Mary Smith
  - Susan Williams

5、yml和yaml

文件扩展名对文件内容没有任何影响。您可以将YAML内容保存在具有任何扩展名的文件中:.yml,.yaml或其他任何扩展名。

YAML FAQ建议您优先使用.yaml而不是.yml,但是由于历史原因,许多Windows程序员仍然害怕使用具有三个以上字符的扩展名,因此选择使用.yml。

因此,真正重要的是文件内部的内容,而不是文件扩展名。

6、常见解析库

可以查看Wiki的推荐:https://zh.wikipedia.org/wiki/YAML

7、Go解析库使用示例

如果你是纯yaml的解析可以使用推荐较多的yaml.v2:https://github.com/go-yaml/yaml

如果可能还有json等格式文件的话则可以使用:https://github.com/jinzhu/configor

我们项目上目前是使用的下面这个,这里也以该库做一个简单的示例。

package main

import (
	"fmt"
	"github.com/jinzhu/configor"
)

var Config = struct {
	AppName string `default:"app name"`

	DB struct {
		Name     string
		User     string `default:"root"`
		Password string `required:"true" env:"DBPassword"`
		Port     uint   `default:"3306"`
	}

	Contacts []struct {
		Name  string
		Email string `required:"true"`
	}
}{}

func main() {
	configor.Load(&Config, "config.yaml")
	fmt.Printf("config: %#v\n", Config)
	fmt.Println("config: ", Config)
}

结果:

config: struct { AppName string "default:\"app name\""; DB struct { Name string; User string "default:\"root\""; Password string "required:\"true\" env:\"DBPassword\""; Port uint "default:\"3306\"" }; Contacts []struct { Name string; Email string "required:\"true\"" } }{AppName:"test", DB:struct { Name string; User string "default:\"root\""; Password string "required:\"true\" env:\"DBPassword\""; Port uint "default:\"3306\"" }{Name:"test", User:"test", Password:"test", Port:0x4d2}, Contacts:[]struct { Name string; Email string "required:\"true\"" }{struct { Name string; Email string "required:\"true\"" }{Name:"i test", Email:"test@test.com"}}}
config:  {test {test test test 1234} [{i test test@test.com}]}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go解析yaml和yml文件 的相关文章

随机推荐

  • 移植python到小米路由器记录。

    最近抢了一个小米路由器 研究了一下 总的来说现在看起来功能还很少 现在比较有用的功能就是 远程下载功能 支持迅雷 电驴等 不过现在看电影啥的都是直接在线看的 基本上也很少用 检测连接的智能设备 这个功能可以随时查看是否有人曾网 当然也可以用
  • git项目初次push提示 error: failed to push some refs to ‘https://github.com/xxx

    问题描述 当你的项目不是先从远程仓库pull下来 再push的话 可能会出现 push被拒绝问题 rejected cfj gt cfj non fast forward error failed to push some refs to
  • 定义样式并获取上传文件路径及指定文件类型

  • dataframe显示数据处理进度

    显示效果如下 tqdm搭配progress apply使用 from tqdm import tqdm tqdm pandas desc pandas bar df result df score progress apply lambda
  • 发现一个bug如何定位是前端还是后台问题?

    1 经验法 软件测试人员应不断精进自己的技能 负责的项目多了 自然对功能的实现过程有了解 也就明白如何分类bug了 例如 网页上的某个图片的分辨率不对 如果我们了解实现过程 可以想到一般情况下 是根据某个地址去服务器取图片的 数据库一般只保
  • c/c++ 力扣LeetCode 645.错误的集合

    题目链接 力扣 645 错误的集合 不想戳的看下图 解题思路 循环嵌套 对于这道题 有很多种方法 首先想到的 应是循环嵌套 直接for循环两边寻找相同 并求得丢失的整数 代码就不展示了 想必大家都会写 但时间复杂度O n2 是相当高的 对于
  • ios html mail,在Ios上的html电子邮件中显示base64图像

    我生成一个包含base64图像的html字符串 当MFMailComposeViewController打开时 我会看到生成的电子邮件中的图像 当我发送并打开它时 图像不会显示 只有空方块 我的代码 IBAction actionShare
  • VSCode无法登录leetcode,报[ERROR] invalid password?错误

    原因 leetcode cn的用户名是手机或者邮箱 不能用昵称登录 在官网退出登陆后发现用昵称登录不了 换成邮箱或者手机号后 登录成功 login node 960 Warning Accessing non existent proper
  • SQL Server主流版本生命周期管理

    SQL Server 生命周期 每个版本的 SQL Server 都有至少 10 年的支持期限 其中包括五年的主要支持和五年的扩展支持 主要支持 包括功能 性能 可伸缩性和安全更新 扩展支持 仅包含安全更新 终止支持 有时也称为生命周期结束
  • 2020年高教社杯全国大学生数学建模竞赛赛题 C题分析与思路!(持续更新)

    C题 中小微企业的信贷决策 1 C题题目背景 分析 在实际中 由于中小微企业规模相对较小 也缺少抵押资产 因此银行通常是依据信贷政策 企业的交易票据信息和上下游企业的影响力 向实力强 供求关系稳定的企业提供贷款 并可以对信誉高 信贷风险小的
  • 【nginx编译-zierror: ‘struct crypt_data‘ has no member named ‘current_salt‘】

    nginx编译 src os unix ngx user c In function ngx libc crypt src os unix ngx user c 26 7 error struct crypt data has no mem
  • C#中Class与Struct区别

    C 中Class与Struct区别 1 class 是引用类型 继承自System Object stuce是值类型 继承自System ValueType类 因此不具多态性 但是注意 System ValueType是个引用类型 2 从职
  • 如何用SPSS对数据进行标准化处理?

    SPSS统计分析软件是我最早接触的数据分析工具 我的博客将陆续介绍SPSS统计分析软件的相关内容 这类文章将统一按照在标题或者正文第一段出现 SPSS案例分析 编号 的形式组织 便于读者朋友们快速查询 收集 今天是第一篇 即 SPSS案例分
  • python循环与文件操作

    if 语句语法结构 if 条件 elif 条件 else 1 如果表达式的值 非0 或者为布尔值 True 则代码组 if suite 被执行 否则就去执行 else suite 2 只要表达式数字为 非零值 即为 True 3 空字符串
  • 移植使用tslib 库

    目录 tslib 简介 tslib 移植 下载tslib 源码 编译tslib 源码 tslib 安装目录下的文件夹介绍 在开发板上测试tslib tslib 库函数介绍 打开触摸屏设备 配置触摸屏设备 读取触摸屏数据 基于tslib 编写
  • STL库的使用之容器模板类QVector使用

    Qt中提供了一组通用的基于模板的容器类 对比C 中的STL库的容器类 Qt的这些容器类更轻量 更安全并且容易使用同时在速度 内存消耗 内联代码等方面进行了优化 存储在Qt的容器中数据必须是可赋值的数据类型 数据类型必须提供一个默认的构造函数
  • BES2300X,BES2500X——UI(按键,提示音,指示灯)

    本文是BES2300X BES2500X系列博文UI部分 一个耳机 音箱 UI是联系使用者与开发者最直接的一个窗口 当然 对于吾等码农而言 UI设计并不是我们最关心的 我们主要做的是UI实现 本文 写BES最基础UI 按键 指示灯 提示音
  • 基于Qt的收银点餐系统之UI的改进——QStackedLayout和QScrollArea的使用

    待解决问题 在收银点餐系统之UI的基本实现中 我们实现了本系统中最基本的UI 这一个UI是静态的 不能够动态添加按钮 关于如何添加见参考资料 也不能实现点击不同的分类 出现不同的界面等 前者的逻辑通过代码很好实现 故不赘述 后者则需要用到一
  • 力扣第45天----第392题、第115题

    力扣第45天 第392题 第115题 文章目录 一 第392题 判断子序列 二 第115题 不同的子序列 一 第392题 判断子序列 挺简单的 思路跟以前的都差不多 class Solution public bool isSubseque
  • Go解析yaml和yml文件

    Go解析yaml和yml文件 文章目录 Go解析yaml和yml文件 1 yaml概述 2 功能 3 示例 4 语言的构成元素 1 清单 数组 2 关系数组 3 区块的字符 4 保留换行 Newlines preserved 5 折叠换行