neslib.yaml是一个用于解析和发射YAML并构建YAML文档和流的库。
neslib.yaml在利比亚姆图书馆的顶部建立,并从事:
安装:
> git clone --recursive https://github.com/neslib/Neslib.Yaml该库仅取决于NESLIB存储库,该存储库包含在此存储库中。
对于除MacOS 32位以外的所有平台,没有运行时依赖关系:LibyAML库直接链接到可执行文件中。对于MacOS 32位,您需要将libyaml_mac32.dylib库将其部署到远程路径ContentsMacOS 。
这是YAML的简短介绍。有关更详细的信息,请查看官方YAML网站或诸如此类的许多在线资源之一。
YAML(“ Yaml ain't Markup语言”的缩写)是一种数据序列化语言。与许多其他类似的基于文本的语言(例如JSON和XML)不同,YAML的主要目标是人类可读,也很容易被人类创造。这就是为什么通常用于配置文件的原因。但是,它可用于各种数据,例如YAML规范中的示例:
invoice : 34843
date : 2001-01-23
bill-to : &id001
given : Chris
family : Dumars
address :
lines : |
458 Walkman Dr.
Suite #292
city : Royal Oak
state : MI
postal : 48046
ship-to : *id001
product :
- sku : BL394D
quantity : 4
description : Basketball
price : 450.00
- sku : BL4438H
quantity : 1
description : Super Hoop
price : 2392.00
tax : 251.42
total : 4443.52
comments : >
Late afternoon is best.
Backup contact is Nancy
Billsmer @ 338-4338. YAML文档是一个值树,称为节点(此库中的TYamlNode )。有4种节点:
映射类似于Delphi词典。映射是密钥/值对的集合。上面示例文档的根笔记是一个映射:它将密钥invoice映射到值34843 ,并包含7个其他密钥/值对(从date到comments )。键和值都可以是任何YAML类型,尽管您可能想坚持使用键的字符串。
映射可以用块符号(如示例中)或流符号(使用卷曲括号{} )写入。
使用块符号时,YAML使用凹痕进行范围。仅允许空间用于凹痕(不是标签)。只要在同一级别上使用相同数量的空间,空间的数量就无关紧要。在示例中, bill-to键的值是另一个映射。该映射缩进以表明它属于按bill-to密钥。
序列就像Delphi数组或列表一样。可以使用流量表示法(使用Square Brackets [] )编写小序列。较大或复杂的序列通常用块符号编写,如示例: product密钥的值是两种产品(篮球和超级箍)的序列。序列中的每个项目都始于仪表板和空间。
在此示例中,序列中的每个产品都是4个键/值对的映射。
所有节点至少具有两个属性: Tag和Anchor 。标签用于描述节点的语义类型。标签并不常见,因此我将在此介绍中跳过它们。 neslib.yaml对标签有全力支持。
可以使用锚来标记文档中的节点。然后,您可以稍后使用别名参考此节点。
锚固式前缀( & )。在示例中, bill-to键的值具有称为id001的锚点(anmpersand不是名称的一部分)。稍后,在文档中, ship-to使用别名引用了此锚点(星号随后是锚名,例如*id001 )。这是一种说明运输地址与帐单地址相同的方式。请注意,别名不复制引用值;它实际上只是指另一个节点。
锚必须在文档引用之前出现在文档中。他们的名字在文档中不必是唯一的。如果以相同名称声明了新的锚,它将取代旧锚。
标量是最简单的类型。所有不是映射,序列或别名的内容都是标量。实际上,标量只是字符串。上面示例中的所有键都是字符串标2001-01-23 ,但是很多值也是(例如34843和Chris )。
YAML 1.1规范(这是利比亚尔使用的)将所有这些标量视为字符串,即使它们是数字或日期,如本示例中。您可以使用标签明确说明特定标量是特定类型的。
该库中的TYamlNode记录提供了ToInteger和ToDouble等方法(尝试)转换为Delphi类型,而不管可能附加到节点上的任何标签。
标量可以用不同的“样式”写:
| )开头。在上面的示例中, bill-to.address.lines值是字面意义。文字中的任何新线都保留了。comments密钥一起使用。YAML还有很多,但这应该涵盖许多用例。
该库的主要切入点是IYamlDocument或IYamlStream接口。
YAML文件可以包含多个文档。如果是这种情况,则应使用IYamlStream加载它。流只是文档的集合(类型IYamlDocument )。
但是,在大多数情况下,YAML文件仅包含一个文档,并且从IYamlDocument开始更容易。加载文档很容易:
var
Doc: IYamlDocument;
begin
Doc := TYamlDocument.Load( ' invoice.yaml ' );
end ;您可以从文件或流中加载,也可以使用TYamlDocument.Parse方法解析yaml文本。
现在,您可以使用IYamlDocument.Root属性来检查文档。此属性为TYamlNode类型,这是所有文档的构建块。
Tyamlnode的实现是使其轻巧的记录。所有节点都是文档的“所有者”。这使内存管理完全自动:一旦文档超出范围,其所有节点将自动释放。这确实意味着,尽管文档范围不足之后,您不应该“坚持”到节点。这样做会导致不确定的行为或违规行为。
例如,要在上面的示例中访问第一个产品的price ,您可以使用以下代码:
Price := Doc.Root.Values[ ' product ' ].Nodes[ 0 ].Values[ ' price ' ].ToDouble;您使用Values属性在映射中通过键访问值。同样, Nodes属性用于按序列中的索引访问值,并且可以使用其中一种ToXXX方法将标量值转换为Delphi DataType。
要检查节点的类型,您可以使用NodeType属性或IsXXX属性之一( IsMapping , IsScalar等)。
您还可以从头开始创建YAML文档,并将其保存到文件或将其转换为YAML。要创建YAML文档,请根据所需的根节点的类型使用TYamlDocument.CreateXXX方法之一。如果要重建示例文档,则从映射开始并致电:
Doc := TYamlDocument.CreateMapping;然后,您可以开始添加键/值对:
Doc.Root.AddOrSetValue( ' invoice ' , 34843 );
Doc.Root.AddOrSetValue( ' date ' , ' 2001-01-23 ' ); AddOrSetValue方法用于将密钥/值对添加到映射。如果节点不是映射,则会提出EInvalidOperation异常。
要添加非量表值,请使用其他AddOrSetXXX方法之一:
var
Products: TYamlNode;
begin
Products := Doc.Root.AddOrSetSequence( ' product ' );
end ;这为关键product添加了映射的序列。然后,您可以使用AddXXX方法之一将值添加到序列中。同样,如果节点不是序列,则会提高EInvalidOperation异常。在示例中,我们需要在此序列中添加另一个映射:
var
Product: TYamlNode;
begin
Product := Products.AddMapping;
Product.AddOrSetValue( ' sku ' , ' BL394D ' );
Product.AddOrSetValue( ' quantity ' , 4 );
// etc...
end ;构建文档后,您可以使用Save方法将其保存到文件或流中,或使用ToYaml方法将其转换为YAML:
var
Yaml: String;
begin
Yaml := Doc.ToYaml;
end ;您可以将可选的TYamlOutputSettings记录传递给自定义YAML格式。
neslib.yaml比上述要多。有关更多详细信息,您可以查看文档良好的Neslib.Yaml.pas源文件。可以在单元测试中找到其他用法样本,尤其是在Tests.Neslib.Yaml.Sample.pas中。
NESLIB.YAML获得了根据简化的BSD许可证的许可。
有关详细信息,请参见License.txt。