不同的 YAML 数组表示

bee*_*ego 6 ruby python yaml pyyaml

我正在使用 Python 和 PyYAML 为一个项目编写文件类型转换器,我在该项目中多次与 YAML 文件相互转换。这些文件随后由我无法控制的单独服务使用,因此我需要将 YAML 翻译回与最初获得的相同。我的原始文件包含以下部分:

key:
- value1
- value2
- value3
Run Code Online (Sandbox Code Playgroud)

其评估为{key: [value1,value2,value3]}使用yaml.load(). 当我将其转换回 YAML 时,我的新文件如下所示:

key: [value1,value2,value3]
Run Code Online (Sandbox Code Playgroud)

我的问题是,就 YAML 文件的各种语言解析器而言,这两种形式是否等效。显然,使用 PyYaml,这些是等效的,但是对于应用程序正在使用的 Ruby 或其他语言,这是否适用?否则,应用程序将无法正确显示数据。

Ant*_*hon 5

正如 Jordan 已经指出的那样,节点样式是一个序列化细节。输出相当于您的输入。

使用 PyYAML,您可以default_flow_style在转储时使用关键字获得相同的块样式输出:

yaml.dump(yaml.load("""\
key:
- value1
- value2
- value3
"""), sys.stdout, default_flow_style=False)
Run Code Online (Sandbox Code Playgroud)

给你:

key:
- value1
- value2
- value3
Run Code Online (Sandbox Code Playgroud)

如果您要使用ruamel.yaml的往返功能(免责声明:我是该软件包的作者),您可以这样做:

import sys
import ruamel.yaml as yaml

yaml_str = """\
key:
- value1
- value2  # this is the second value
- value3
"""

data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)

yaml.dump(data, sys.stdout, Dumper=yaml.RoundTripDumper, default_flow_style=False)
Run Code Online (Sandbox Code Playgroud)

要得到:

key:
- value1
- value2  # this is the second value
- value3
Run Code Online (Sandbox Code Playgroud)

它不仅保留了流/块样式,而且还保留了注释和键顺序,以及一些更透明的。这使得比较(例如,当使用某些版本控制系统检入 YAML 文件时)更加容易。

对于读取 YAML 文件的服务,这一切都没有区别,但为了便于检查您是否正确地转换了东西,它确实如此。


Jor*_*ing 4

是的,对于任何遵循规范的 YAML 解析器,它们是等效的。您可以在此处阅读规范:http://www.yaml.org/spec/1.2/spec.html

第 3.2.3.1 节特别相关(重点是我的):

3.2.3.1. 节点样式

每个节点都以某种样式呈现,具体取决于其类型。节点样式是表示细节,不会反映在序列化树或表示图中。有两组样式。块样式使用缩进来表示结构;相反,流程样式依赖于明确的指示符。

澄清一下,节点是 YAML 中的任何结构,包括数组(在规范中称为序列)。单线样式称为流序列(参见第 7.4.1 节),多线样式称为块序列(第 8.2.1 节)。兼容的解析器会将两者反序列化为相同的对象。