我需要将.yml文件分解为3个部分:页眉,工作(我需要编辑的部分)和页脚。标头是“ Resource:”块之前的所有内容,而页脚是资源块之后的所有内容。本质上,我需要创建代码来创建3个列表,字典,字符串,无论做什么工作,这些代码都保存YAML文件的这三个部分,然后允许我针对该工件运行更多代码,然后将所有代码最后连接在一起,产生具有相同缩进的新文档。不应更改标题或尾部。
注意:我已经查找了有关yaml解析的所有内容,但似乎无法有效地实现我发现的建议。首选不涉及导入yaml的解决方案,但是如果您必须这样做,请解释一下导入yaml代码的真正含义,以便我理解我的理解。
答案 0 :(得分:0)
包含一个或多个YAML文档(简称:YAML文件,自
建议您在2006年9月使用扩展名.yaml
)
文本文件,并且可以从各个部分进行串联。唯一的要求是
最后,您将获得一个文本文件,该文件是有效的YAML文件。
最简单的当然是将页眉和页脚分开 文件,但是当您谈论多个YAML文件时, 很快变得笨拙。但是总是可以做一些基本的 解析文件内容。
由于您的工作部分以Resource:
开头,因此您指定了3
列表或字典(一个字符串的根不能有三个字符串
YAML文件)。 YAML文档的根级别数据结构
必须是 mapping 以及其他所有内容,除了
映射的键需要缩进(理论上,它只需要
缩进更多,但实际上这几乎总是意味着
键不缩进),例如(m.yaml
):
# header
a: 1
b:
- 2
- c: 3 # end of header
Resource:
# footer
c:
d: "the end" # really
或根级别必须是一个序列(s.yaml
):
# header
- a: 1
b:
- 2
- c: 3
- 42 # end of header
- Resource:
# footer
- c:
d: "the end" # really
两者都可以很容易地拆分,而无需加载YAML,这是为此的示例代码 具有根级别映射的文件:
from pathlib import Path
from ruamel.yaml import YAML
inf = Path('m.yaml')
header = [] # list of lines
resource = []
footer = []
for line in inf.open():
if not resource:
if line.startswith('Resource:'): # check if we are at end of the header
resource.append(line)
continue
header.append(line)
continue
elif not footer:
if not line or line[0] == ' ': # still in the resource part
resource.append(line)
continue
footer.append(line)
# you now have lists of lines for the header and the footer
# define the new data structure for the resource this is going to be a single key/value dict
upd_resource = dict(Resource=['some text', 'for the resource spec', {'a': 1, 'b': 2}])
# write the header lines, dump the resource lines, write the footer lines
outf = Path('out.yaml')
with outf.open('w') as out:
out.write(''.join(header))
yaml = YAML()
yaml.indent(mapping=2, sequence=2, offset=0) # the default values
yaml.dump(upd_resource, out)
out.write(''.join(footer))
print(outf.read_text())
这给出了:
# header
a: 1
b:
- 2
- c: 3 # end of header
Resource:
- some text
- for the resource spec
- a: 1
b: 2
# footer
c:
d: "the end" # really
在解析YAML文件的同时执行相同操作并不困难。以下自动处理 两种情况(根级别是映射还是序列):
from pathlib import Path
from ruamel.yaml import YAML
inf = Path('s.yaml')
upd_resource_val = ['some text', 'for the resource spec', {'a': 1, 'b': 2}]
outf = Path('out.yaml')
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, sequence=2, offset=0)
yaml.preserve_quotes = True
data = yaml.load(inf)
if isinstance(data, dict):
data['Resource'] = upd_resource_val
else: # assume a list,
for item in data: # search for the item which has as value a dict with key Resource
try:
if 'Resource' in item:
item['Resource'] = upd_resource_val
break
except TypeError:
pass
yaml.dump(data, outf)
这将创建以下out.yaml
:
# header
- a: 1
b:
- 2
- c: 3
- 42 # end of header
- Resource:
- some text
- for the resource spec
- a: 1
b: 2
# footer
- c:
d: "the end" # really
如果已输入m.yaml
文件,则输出将具有
与基于文本的“串联”示例代码完全相同。