当前位置: 首页 > 工具软件 > TOML > 使用案例 >

toml 格式文件解析

翟聪
2023-12-01

toml 文件格式是在 yaml 之后被鼓捣出来的,所以,在文件编写以及解析上,都会比 yaml 文件更简单一些。

掌握 yaml 的解析,核心在于了解 yaml 的设计理念:TOML is designed to map unambiguously to a hash table。toml 被设计从无序的 hash 表结构,键值对的方式。键的类型是字符串,值得类型比较多样,可以是单值类型、数组、结构体

在 go 语言的背景下,toml 需要按照 map 文件的方式进行解析。我们可以将 toml 映射成 map[string]interface{} 的类型。通过映射后来的类型,来了解整个文件的解析过程

下面是从 toml 获取的示例,我们可以将 toml 转换成 json ,通过对比输出的 json,可以了解到 toml 转换的对应关系。

# This is a TOML document

title = "TOML Example"

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00

[database]
enabled = true
ports = [ 8000, 8001, 8002 ]
data = [ ["delta", "phi"], [3.14] ]
temp_targets = { cpu = 79.5, case = 72.0 }

[servers]

[servers.alpha]
ip = "10.0.0.1"
role = "frontend"

[servers.beta]
ip = "10.0.0.2"
role = "backend"

下面是 go 的转换,代码中的 conf 就是上面的 toml 示例。

也比较好理解,转换的关键是无序 map 中 key 的对应关系。toml 中如何确定第一层 map 的 key 有哪些,这些 key 对应的值都应该怎么做归属?

[table] 在 toml 中被定义为独立的表格,也就是键值对的 key。在遇到下一下 [table] 之前的所有内部,都属于这个 key 的内容。所以说,[table] 其实是作为分界使用的。

func main() {
	data := make(map[string]interface{})
	// conf 为 toml 的示例
	if err := toml.Unmarshal([]byte(conf), &data); err == nil {
		out, _ := json.Marshal(data)
		fmt.Println(string(out))
	}
}

我们还会定义 [table.sub] 这样的二级结构,来表明 sub 这个 key 从属于 table 这个 key,因为是无序的,所以,[table.sub] 可以定义在 toml 文件的任意位置。

比方说,我们在上述文件的末尾追加下面的内容,toml 文件也可以正常进行解析。尽管,database 的定义区块是分割开的。

[database.name]
default = "shanghai"

数组类型

在 toml 中如何定义表格数组呢?使用 [[table]] 符号。一定要区分数组类型和表格数组。想象一下,如果我们要表示一个对象数组该何如表示?

一个对象会包含多个属性定义,如果我们使用 [table] 只能表示一个,如果我们使用 [[table]] 就是表示要将 table 对应一个对象数组的形式。

比方,对上面的代码示例做下面的调整,在解析后的 map 结构中,alpha 对应的就是一个数组对象。

[[servers.alpha]]
ip = "10.0.0.1"
role = "frontend"

[[servers.alpha]]
ip = "10.0.0.2"
role = "frontend"
 类似资料: