加载带有嵌入式 JSON 的 YAML 时格式不正确(没有换行符)

Incorrect format (No newline chars) when loading YAML with embedded JSON

我正在尝试解析来自文件的 YAML 输入:

root: {
   children : { key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}
}

我正在使用 ruamel.yaml,加载的代码部分配置为保留引号,然后我手动添加一个新条目:

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.width = 4096
yaml.indent(sequence=4, offset=2)

with open(yml_file, 'r') as file:
   print("Modifying file: '%s'..." % str(file))
   data = yaml.load(file)

data['root'][new_project_name.lower()] = {'key': "%s" % new_project_name.lower(),
                                                          'test_version': "{{ %s_version | default(\'1.0.0-SNAPSHOT\') }}"
                                                                     % new_project_name.lower()}

 with open(yml_file, 'w') as file:
       yaml.dump(data, file)

问题是,当用新条目写入文件时,我将所有内容都放在同一行中,所以它似乎没有保留新行 (CR LF),(似乎在没有加载它的情况下他们甚至)你知道有没有办法保存它们?

输出是(同一行中的所有内容):

root: {children : { key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}}

ruamel.yaml 不保留注释,也不保留流中的间距 风格。如果你关心布局,那么你的 YAML 更容易 人类阅读,你应该最大程度地使用流式风格 节点,如果有的话。这是使用 YAML(typ='fast').

时的默认转储样式

当您的输入具有嵌套流式时,这些节点上的流式是 保留,并完成标准格式设置(如果该行换行除外 变得很大,一切都在一条线上)。

设置缩进级别仅影响块样式结构。

为了更好的可读性,您应该将输入更改为仅叶节点流式:

root: 
   children: {key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}

这会加载到与您的输入相同的数据结构。

现在您可以这样做:

import sys
import ruamel.yaml

yml_file = 'input.yaml'
new_project_name = 'NPN'


yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.width = 4096

with open(yml_file, 'r') as file:
   print("Modifying file: '%s'..." % str(file))
   data = yaml.load(file)

npn_lower = new_project_name.lower()

data['root'][npn_lower] = m = ruamel.yaml.comments.CommentedMap([
    ('key',  "%s" % npn_lower),
    ('test_version', "{{ %s_version | default(\'1.0.0-SNAPSHOT\') }}" % npn_lower)
])
m.fa.set_flow_style()

with open('output.yaml', 'w') as fp:
    yaml.dump(data, fp)

打印:

Modifying file: '<_io.TextIOWrapper name='input.yaml' mode='r' encoding='UTF-8'>'...

并且有 output.yaml:

root:
  children: {key: "test-key", version: "{{ test_version | default( '1.0.0-SNAPSHOT' ) }}"}
  npn: {key: npn, test_version: "{{ npn_version | default('1.0.0-SNAPSHOT') }}"}

注意事项:

  • 添加一个 CommentedMap,因为在普通字典上你不能单独设置 流式,你需要这样做,因为这不再是嵌套的 流式。元素作为元组列表添加,与 Python 的旧版本不能保证密钥顺序是 与您的输入相同。您还创建了一个空的 CommentedMap() 和 一次添加 keys/value 对。

  • 在尝试的过程中(以及此处提供的代码)它总是 更改输入文件是个坏主意,对于每个测试-运行 你的 必须还原输入。