parentelement

parentelement

1.什么是TOML?

汤姆的全名是[汤姆& # 39;s明显的极简语言],由GitHub联合创始人撰写。

TOML的目标是成为一种极简的配置文件格式,它被设计成明确地映射到一个散列表,从而可以被许多语言解析。

官网地址:TOML:Tom & # 39;显而易见的最小语言

2.官方示例

#这是一个TOML文档。= & # 34TOML示例& # 34;[owner]name = & # 34;汤姆·普雷斯顿-沃纳& # 34;DOB = 1979-05-27t 07:32:00-08:00 # first class dates #日期和时间是一等公民[数据库]服务器= & # 34;192.168.1.1"Ports = [8000,8001,8002]connection _ max = 5000 enabled = true[servers]#随意缩进[servers . alpha]IP = & # 34;10.0.0.1"dc = & # 34eqdc10 & # 34[servers . beta]IP = & # 34;10.0.0.2"dc = & # 34eqdc10 & # 34[客户]数据=[[& # 34;伽马& # 34;, "△& # 34;],[1,2] ]#您可以在数组hosts =[& # 34;阿尔法& # 34;, "欧米茄& # 34;]

1)注意事项

TOML认为所有的配置文件都应该支持注释。

#这是一个TOML注释#这是一个多行的# TOML注释

2)数值

支持整数、浮点数、无穷大甚至NaN。你可以使用科学符号,甚至数千个分隔符。

# integers int 1 =+99 int 2 = 42 int 3 = 0 int 4 =-17 #十六进制带前缀` 0x ` hex 1 = 0x dead beefhex 2 = 0x dead _ beef #八进制带前缀` 0O ‘oct1 = 0O01234567Oct2 = 0O755 #二进制带前缀` 0b ‘bin1 = 0b11010110 #小数float 1 =+1.0 float 2 = 3.1415 float 3 =-0

3)布尔型

布尔值总是小写。

bool1 = truebool2 = false

4)强有力的琴弦

字符串有四种表达方式:基本表达式、多行基本表达式、字面量、多行字面量。

基本表达式:用单引号括起来。

str1 = & # 34我& # 39;我是一根绳子。"str2 = & # 34你可以\ & # 34;报价\ & # 34;我。"str3 = & # 34Name\tJos\u00E9\nLoc\tSF。"str = & # 34我& # 39;我是一根绳子。\"你可以引用我的话\ & # 34;。Name\tJos\u00E9\nLocation\tSF。"

可以使用任何Unicode字符,除了那些必须转义的字符:除引号、反斜杠和制表符之外的控制字符(U+0000到U+0008、U+000A到U+001F、U+007F)。

为了方便起见,一些常用字符有一个紧凑的转义序列:

\b -退格(U+0008)\t – tab (U+0009)\n -换行(U+000A)\f -换页(U+000C)\r -回车(U+000d)\ & # 34;- quote (U+0022)\反斜线(U+005 c)\ uxxxxxx-unicode(U+XXXX)\ UXXXXXXXX-unicode(U+XXXXXXXX)

任何Unicode字符都可以以\ uxxxxx或\ uxxxxxxxxx格式进行转义。转义码必须是有效的Unicode标量值。

多行基本表达式:用三个双引号括起来,允许换行。在行尾的任何非空字符前面包含一个反斜杠,该反斜杠会被自动删除。

str1 = & # 34""玫瑰是红色的,紫罗兰是蓝色的& # 34;""str2 = & # 34""快速的棕色狐狸跳过懒狗。\ """

Str2变成& # 34;那只敏捷的棕色狐狸跳过了那只懒狗。"(没有换行符的句子)

字面量:用单引号括起来,不转义。

path = & # 39c:\ Users \ nodejs \ templates & # 39;path2 = & # 39\ \ User \ admin $ \ system32 & # 39quoted = & # 39汤姆& # 34;配音& # 34;普雷斯顿-沃纳& # 39;regex = & # 39& lt\ i \ c * \ s * & gt'

因为没有转义,所以不能在用单引号括起来的字符串中写单引号。这就是多行字符串的起源:

re = & # 39''\d{2}应用程序太多了& # 39;''lines = & # 39''原始字符串中的第一个换行符。所有其他空白被保留。'''

5)日期和时间

TOML支持日期、时间和日期时间。您可以包括或不包括时间间隔。

# offset datetime ODT 1 = 1979-05-27t 07:32:00 zodt 2 = 1979-05-27t 00:32:00-07:00 ODT 3 = 1979-05-27t 00:32:00.999999-07:00 # local datetime ldt 1 = 1979-05-27t 07:32:00 ldt 2 = 1979-05

6)键-值对键/值

key = & # 34价值& # 34;

键和值之间的空网格被忽略。

Key、=、value必须在同一行。

值必须是以下类型之一:字符串、整数、浮点、布尔、偏移日期时间、本地日期时间、本地日期、本地时间、数组、内联表。

不指定值是无效的:

key = # INVALID

键/值对后面必须跟一个换行符(或EOF):

first = & # 34汤姆& # 34;last = & # 34普雷斯顿-沃纳& # 34;#无效

7)钥匙

键可以是一个基本的表示,用引号和& # 34;。"符号的

基本键的表示只能包含ASCII字母、ASCII数字、下划线和水平线(A-Za-z0-9_-)。请注意,只允许ASCII数字,如1234,但它们总是被解释为字符串。

key = & # 34价值& # 34;bare _ key = & # 34价值& # 34;bare-key = & # 34;价值& # 34;1234 = "价值& # 34;

带引号的关键字:

"127.0.0.1"= "价值& # 34;"字符编码& # 34;= "价值& # 34;"ʎǝʞ"= "价值& # 34;'key2 & # 39= "价值& # 34;'引用& # 34;价值& # 34;'= "价值& # 34;

遵循与基本字符串或大量字符串完全相同的规则,并允许您使用更多的键名。但是,这是不必要的,也不推荐。

一般情况下,键必须是非[/k0/],但允许使用空的引号(虽然不鼓励)。

= "没有键名& # 34;#无效& # 34;"= "blank & # 34#有效但不鼓励& # 39;'= 'blank & # 39#有效但不鼓励

用“.”键符号:相似的属性可以组合在一起。

name = & # 34Orange & # 34physical.color = & # 34orange & # 34physical.shape = & # 34round & # 34网站。"google.com & # 34= true

转换成JSON格式,会显示如下:

{ "姓名& # 34;: "Orange & # 34, "物理& # 34;: { "color & # 34: "orange & # 34, "形状& # 34;: "round & # 34}, "网站& # 34;: { "google.com & # 34:true }}

“.”周围的空框将被忽略,最好不要使用任何不相关的空空白。

fruit.name = & # 34香蕉& # 34;#这是最佳实践。color = & # 34黄色& # 34;#与fruit.colorfruit相同。flor = & # 34香蕉& # 34;#与fruit.flor相同

缩进被认为是空,将被忽略。

多次定义一个键是无效的。

#不要这样做name = & # 34;汤姆& # 34;name = & # 34普拉东& # 34;

请注意,带引号的键和不带引号的键是等效的:

#这样不行= & # 34;最爱& # 34;"拼写& # 34;= "最爱& # 34;

只要键没有被直接定义,你仍然可以写它和它里面的名字。

#这使得关键& # 34;水果& # 34;变成一个表。fruit.apple.ooth = true#这样你就可以添加到表& # 34;水果& # 34;像这样:fruit.orange = 2#下面是无效的#这将fruit.apple的值定义为一个整数fruit.apple = 1#但是这样对待fruit.apple就像这样& # 39;这是一张桌子。#你可以& # 39;t将整数转换成表格。fruit.apple.ooth = true

不鼓励定义无序的点键:

#有效但不鼓励使用dapple . type = & # 34;水果& # 34;orange.type = & # 34水果& # 34;apple.skin = & # 34瘦& # 34;orange.skin = & # 34厚& # 34;apple.color = & # 34红色& # 34;orange.color = & # 34orange & # 34

# RECOMMENDEDapple.type = & # 34水果& # 34;apple.skin = & # 34瘦& # 34;apple.color = & # 34红色& # 34;orange.type = & # 34水果& # 34;orange.skin = & # 34厚& # 34;orange.color = & # 34orange & # 34

因为最基本的键可以由ASCII整数组成,所以带点号的键可能会写成浮点数的样子,不推荐。

3.14159 = "pi & # 34

到JSON格式的映射如下所示:

{ "3": { "14159": "pi & # 34} }

8)阵列

数组是带值的方括号。空网格将被忽略。元素由逗号分隔。数组可以包含键/值对中允许的相同数据类型的值。不同类型的值可以混合使用。

integers = [ 1,2,3]colors =[& # 34;红色& # 34;, "黄色& # 34;, "绿色& # 34;]nested_arrays_of_ints = [ [ 1,2 ],[3,4,5] ]nested_mixed_array = [ [ 1,2 ],[& # 34;一& # 34;, "b & # 34, "c & # 34]]string _ array =[& # 34;所有& # 34;, '字符串& # 39;, """都是一样的& # 34;"", '''类型& # 39;'']#允许混合类型数组numbers = [ 0.1,0.2,0.5,1,2,5]contributor =[& # 34;Foo Bar & ltfoo @ example.com & gt",{ name = & # 34Baz Qux & # 34,邮箱= & # 34;bazqux @ example.com & # 34,url = & # 34https://example.com/bazqux" }]

数组可以跨越多行。数组的最后一个值后允许有终止逗号(也称为尾随逗号)。值、逗号和右括号前面可以有任意数量的换行符和注释。数组值和逗号之间的缩进被视为空单元格并被忽略。

整数2 = [ 1,2,3]整数3 = [ 1,2,#这没问题]

9)表格

表(也称为哈希表或字典)是键/值对的集合。它们由标题定义,方括号在一行中。您可以区分头文件和数组,因为数组始终只是值。

[表格]

在它下面,直到下一个标题或EOF,是表的键/值。不能保证表中的键/值对有任何特定的顺序。

[表1]key 1 = & # 34;一些字符串& # 34;key 2 = 123[table-2]key 1 = & # 34;另一串& # 34;key2 = 456

表的命名规则与键的命名规则相同:

【狗。"tater.man & # 34]type . name = & # 34;帕格& # 34;

转换后的JSON格式如下:

{ "狗& # 34;: { "tater.man & # 34: { "类型& # 34;: { "姓名& # 34;: "帕格& # 34;} } } }

键周围的空网格被忽略。但是,最佳做法是不要使用任何不相关的空白色。

[a.b.c] #这是最佳做法[ d.e.f ] #与[d.e.f][ g . h . i ]相同#与[g . h . I][j . & # 34;ʞ"。'l & # 39] #同[j . & # 34;ʞ"。'l & # 39]

缩进被视为空白色并被忽略。

您不需要指定所有的超级表。TOML可以自动处理。

# [x]你# [x.y]唐& # 39;t# [x.y.z]需要这些[x.y.z.w] #这样才能工作[x] #以后定义一个超表是可以的

允许空表,但其中没有键/值对。

像Key一样,一个表不能被定义多次。这样做是没有用的。

#不要这样做[水果]苹果= & # 34;红色& # 34;【水果】橘子= & # 34;orange & # 34

#也不要这样做[水果]苹果= & # 34;红色& # 34;[fruit . apple]纹理= & # 34;平稳& # 34;

不鼓励不按顺序定义表。

#有效但不鼓励[fruit . apple][animal][fruit . orange]

#推荐[水果.苹果][水果.橘子][动物]

顶层表格也称为根表格,从文档的开头开始,在第一个标题(或EOF)之前结束。与其他表不同,它是无名的,不能重定位。

#顶层表格开始。= & # 34菲多& # 34;品种= & # 34;帕格& # 34;#顶级表结束。[owner]name = & # 34;里贾纳·道格曼& # 34;member_since = 1999-08-04

一把带点的钥匙。在最后一个关键部分之前,为每个关键部分创建并定义一个表,前提是以前没有创建过这样的表。

fruit . apple . color = & # 34;红色& # 34;#定义名为fruit的表#定义名为fruit.apple fruit.apple.taste . sweet = true的表#定义名为fruit . apple . taste的表# fruit和fruit . apple已经创建

因为不能多次定义表,所以不允许使用[table]头文件重新定义这些表。同样,不允许使用带“.”的键重新定义以[表格]形式定义的表格。但是,[table]表单可用于在由带“.”的键定义的表中定义子表。

[水果]apple . color = & # 34;红色& # 34;apple . taste . sweet = true #[fruit . apple]# INVALID #[fruit . apple . taste]# INVALID[fruit . apple . texture]#可以添加子表ooth = true

10)内嵌表格

内联表格为表示表格提供了更紧凑的语法。它们对数据分组特别有用,否则这些数据很快就会变得冗长。内联表完全用花括号定义:{和}。在大括号内,可以出现零个或多个逗号分隔的键/值对。键/值对的形式与标准表中的形式相同。允许所有值类型,包括内联表。

内联表格旨在显示在一行上。行内表中最后一个键/值对之后不允许有终止逗号(也称为尾随逗号)。除非换行符在值内有效,否则大括号之间不允许换行符。尽管如此,还是不鼓励将内联表拆分成多行。如果你发现自己被这种欲望所控制,这意味着你应该使用标准形式。

name = { first = & # 34汤姆& # 34;,last = & # 34普雷斯顿-沃纳& # 34;}point = { x = 1,y = 2 } animal = { type.name = & # 34帕格& # 34;}

上面的内嵌表与下面的标准表相同:

[name]first = & # 34;汤姆& # 34;last = & # 34普雷斯顿-沃纳& # 34;[点]x = 1y = 2[动物]type . name = & # 34;帕格& # 34;

内联表是完全独立的,并定义了其中的所有键和子表。不能在大括号外添加键和子表。

[产品]type = { name = & # 34;钉钉& # 34;} # type . edible = false # INVALID

同样,内联表不能用于向定义的表中添加键或子表。

[产品]type . name = & # 34;钉钉& # 34;# type = {可食=假} #无效

11)表格阵列

头文件的第一个实例定义了一个数组及其第一个表元素,每个后续实例在数组中创建和定义一个新的表元素。表格按照遇到的顺序插入到数组中:

[[产品]]name = & # 34;哈默& # 34;SKU = 738594937[[产品]] #数组中的空表[[产品]]name = & # 34;钉钉& # 34;sku = 284758393color = & # 34格雷& # 34;

转换后的JSON格式如下:

{ "产品& # 34;: [ { "姓名& # 34;: "哈默& # 34;, "sku & # 34: 738594937 }, { }, { "姓名& # 34;: "钉钉& # 34;, "sku & # 34: 284758393, "color & # 34: "格雷& # 34;} ]}

对表数组的任何引用都指向数组中最近定义的表元素。这允许您在最近的表中定义子表甚至表的子数组。

[[水果]]name = & # 34;苹果& # 34;[fruits . physical]# subtable color = & # 34;红色& # 34;shape = & # 34round & # 34[[fruits.varieties]] #嵌套的表数组= & # 34红色美味& # 34;[[水果.品种]]name = & # 34;史密斯奶奶& # 34;[[水果]]name = & # 34;香蕉& # 34;[[水果.品种]]name = & # 34;车前草& # 34;

转换后的格式如下:

{ "水果& # 34;: [ { "姓名& # 34;: "苹果& # 34;, "物理& # 34;: { "color & # 34: "红色& # 34;, "形状& # 34;: "round & # 34}, "品种& # 34;: [ { "姓名& # 34;: "红色美味& # 34;}, { "姓名& # 34;: "史密斯奶奶& # 34;} ] }, { "姓名& # 34;: "香蕉& # 34;, "品种& # 34;: [ { "姓名& # 34;: "车前草& # 34;} ] } ]}

如果表或表数组的父元素是数组元素,则必须在定义子元素之前定义它。试图颠倒此顺序必然会在解析时产生错误。

# INVALID TOML DOC[fruit . physical]# subtable,但是它应该属于哪个父元素呢?color = & # 34红色& # 34;shape = & # 34round & # 34[[fruit]] #解析器必须在发现& # 34;水果& # 34;是一个数组而不是一个表名= & # 34;苹果& # 34;

试图追加静态定义的数组,即使该数组是空,在解析时也会产生错误。

#无效的TOML DOCfruits = [][[fruits]] #不允许

试图定义一个与已建立的数组同名的普通表必然会在解析时产生错误。试图将普通表重定义为数组也会产生解析时错误。

#无效的TOML文档[[水果]]name = & # 34;苹果& # 34;[[水果.品种]]name = & # 34;红色美味& # 34;# INVALID:此表与以前的表数组[fruits . varieties]name = & # 34;史密斯奶奶& # 34;[fruits . physical]color = & # 34;红色& # 34;shape = & # 34round & # 34# INVALID:此表格数组与前一个表格[[fruits . physical]]color = & # 34;绿色& # 34;

在适当的情况下,您也可以使用内嵌表格:

points = [ { x = 1,y = 2,z = 3 },{ x = 7,y = 8,z = 9 },{ x = 2,y = 4,z = 8 } ]

12)文件扩展名

TOML文件应该使用。toml扩展。

13)MIME类型

在internet上传输TOML文件时,合适的MIME类型是application/ toml。

2.NSQD对TOML的使用

1)第三方库:

编辑

或者单独获取:

去获取github . com/burn tsushi/toml

2)创建example.toml

#这是一个TOML文档。Boom.title = & # 34TOML示例& # 34;[owner]name = & # 34;汤姆·普雷斯顿-沃纳& # 34;组织= & # 34;GitHub & # 34bio = & # 34GitHub联合创始人兼首席执行官\ n喜欢土豆泥和啤酒。"dob = 1979-05-27T07:32:00Z #头等舱日期?为什么不呢?[数据库]服务器= & # 34;192.168.1.1"ports = [ 8001,8001,8002]connection _ max = 5000 enabled = true[servers]#可以随意缩进。制表符或空格。汤姆·唐& # 39;我不在乎。[servers . alpha]IP = & # 34;10.0.0.1"dc = & # 34eqdc10 & # 34[servers . beta]IP = & # 34;10.0.0.2"dc = & # 34eqdc10 & # 34[客户]数据=[[& # 34;伽马& # 34;, "△& # 34;],[1,2] ] #只是一个更新,以确保解析器支持它#在arrays hosts =[& # 34;阿尔法& # 34;, "欧米茄& # 34;]

2.分析这个toml文件并创建表和结构之间的对应关系:

汤姆的桌子

Go结构

配置文件

tomlConfig

物主

ownerInfo

数据库

数据库

服务器

计算机网络服务器

服务器. alpha

计算机网络服务器

servers.beta

计算机网络服务器

客户

客户

分析代码的整个文件的TomlConfig结构应该具有以下属性:

TitleownerInfodatabasemap[string]server,因为Table本身就是键值对的集合。clients

客户端结构应该具有以下属性:

Data [][]interface{}:二维数组Hosts []string: 数组

因为服务器是根据键值来区分的,所以服务器结构的正确属性是:

IP stringDC string

整个结构的代码如下:

type toml config struct { Title string Owner Owner info DB database ` toml:& # 34;数据库& # 34;` Servers map[string]Server Clients Clients } type Server struct { IP string DC string } type database struct { Server string Ports[]int ConnMax int ` toml:& # 34;connection _ max & # 34` Enabled bool } type clients struct { Data[][]interface { } Hosts[]string } type owner info struct { Name string Org string ` toml:& # 34;组织& # 34;`生物字符串出生时间。时间}

分析

Func main() {//配置文件结构变量varconfig tomlconfig//将toml值映射到govalues if _,err:= toml . deco c(& # 34;interview/toml/example . toml & # 34;,& config);呃!= nil { fmt。Println(err) return } fmt。printf(& # 34;标题:% s \ n & # 34,配置。标题)fmt。printf(& # 34;所有者:%s (%s,%s),出生:% s \ n & # 34,配置。所有者。名称,配置。Owner.Org,config所有者。简历,配置。Owner.DOB) fmt。printf(& # 34;数据库:%s %v(最大连接数%d),是否已启用?% v \ n & # 34,配置。数据库服务器,配置。数据库端口,配置。DB.ConnMax,config。DB . Enabled ), server:= range config。服务器{ fmt。printf(& # 34;服务器:%s,(%s,% s)\ n & # 34;,服务器名,服务器。IP,服务器。DC) }。printf(& # 34;客户端数据:% v \ n & # 34,配置。客户端.数据)fmt。printf(& # 34;客户端主机:% v \ n & # 34,配置。Clients.Hosts)}

输出结果:

标题:TOML示例所有者:Tom Preston-Werner (GitHub,GitHub联合创始人兼首席执行官)喜欢土豆和啤酒。),出生时间:1979-05-27 07:32:00+0000 utc database:192 . 168 . 1 . 1[8001 8001 8002](最大连接数5000),启用?trueServer: alpha,(10.0.0.1,eqdc10)Server: beta,(10.0.0.2,eqdc 10)Client data:[[gamma delta][1 2]]Client hosts:[alpha omega]

主要采用以下方法:

//deco c就像Decode一样,只是它会自动读取’ fpath ‘处文件的//内容并为您解码。func deco c(fpath string,v interface{}) (MetaData,error)

最后,通过反射对文件进行解析和映射。主要核心代码如下:

func Decode(数据字符串,v接口{})(元数据,错误){ rv := reflect。rv时的(v)值。Kind()!=反思。Ptr {返回元数据{},e(& # 34;非指针%s的解码& # 34;,反思。TypeOf(v)) } if rv。IsNil() { return MetaData{},e(& # 34;nil %s的解码& # 34;,反思。TypeOf(v)) } p,err := parse(data) if err!= nil { return MetaData{},err } md := MetaData{ p.mapping,p.types,p.ordered,make(map[string]bool,len(p.ordered)),nil,} return md,md.unify(p.mapping,indirect(rv))}

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论