我正在尝试将JSON数据转换为YAML格式,但是获得了意外的YAML输出
使用在线工具将JSON转换为YAML,从而提供预期的YAML输出。但是,当以下Python代码中使用相同的JSON时,会得到意外的不同结果。
import yaml
job_template = [
{
"job-template": {
"name": "{name}_job",
"description": "job description",
"project-type": "multibranch",
"number-to-keep": 30,
"days-to-keep": 30,
"scm": [
{
"git": {
"url": "{git_url}"
}
}
]
}
}
]
yaml.dump(job_template, open("job_template.yaml", "w"))
期望以下YAML数据:
- job-template:
name: "{name}_job"
description: job description
project-type: multibranch
number-to-keep: 30
days-to-keep: 30
scm:
- git:
url: "{git_url}"
获取以下YAML格式:
- job-template:
days-to-keep: 30
description: job description
name: '{name}_job'
number-to-keep: 30
project-type: multibranch
scm:
- git: {url: '{git_url}'}
答案 0 :(得分:1)
使用function validate() {
let isChecked = false;
if (document.getElementById(('filterTodo').checked)) {
isChecked = true;
console.log(isChecked);
} else {
isChecked = false;
console.log(isChecked);
}
}
例如:
default_flow_style=False
答案 1 :(得分:1)
问题出在Python代码中:dict
是无序容器。 pprint
仅给出与yaml输出相同的顺序:
>>> pprint.pprint(job_template)
[{'job-template': {'days-to-keep': 30,
'description': 'job description',
'name': '{name}_job',
'number-to-keep': 30,
'project-type': 'multibranch',
'scm': [{'git': {'url': '{git_url}'}}]}}]
如果问题是关于最后一级字典{"url": "{git_url}"}
的表示形式,则答案由@Rakesh给出
答案 2 :(得分:0)
PyYAML中顺序的更改阻碍了对YAML文件的往返编辑,并且许多其他解析器都试图解决该问题。
值得一看的是Ruamel.yaml,上面写着overview page:
block style and key ordering are kept, so you can diff the round-tripped source
作者提供的代码示例对此进行了说明:
import sys
import ruamel.yaml as yaml
yaml_str = """\
3: abc
conf:
10: def
3: gij # h is missing
more:
- what
- else
"""
data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)
data['conf'][10] = 'klm'
data['conf'][3] = 'jig'
yaml.dump(data, sys.stdout, Dumper=yaml.RoundTripDumper)
will give you:
3: abc
conf:
10: klm
3: jig # h is missing
more:
- what
- else
对此进行了更全面的讨论here。它被描述为是PyYAML的直接替代品,因此应该易于在您的环境中进行实验。
答案 3 :(得分:-1)
首先,您应该将工作模板保留在JSON文件中,例如input.json
。:
[
{
"job-template": {
"name": "{name}_job",
"description": "job description",
"project-type": "multibranch",
"number-to-keep": 30,
"days-to-keep": 30,
"scm": [
{
"git": {
"url": "{git_url}"
}
}
]
}
}
]
这样,您可以更轻松地调整脚本以处理不同的文件。并且这样做 还可以保证JSON对象中的键是有序的,当您将JSON作为dicts和list包含在代码中时,这是不能保证的,至少对于所有当前版本的Python而言并非如此
然后,因为YAML 1.2(规范于2009年发布)是的超集
YAML,您可以只使用保留关键顺序的YAML 1.2库
加载转储时将其转换为所需的格式。以来
PyYAML仍然停留在2005年发布的YAML 1.1规范中,您
不能使用它,但是您可以使用ruamel.yaml
(免责声明,我是
该软件包的作者)。
唯一的“问题”是ruamel.yaml
也将保留
(流)样式的输入。那正是你所不想要的。
因此,您必须递归遍历数据结构并更改 包含该信息的属性:
import sys
import ruamel.yaml
def block_style(d):
if isinstance(d, dict):
d.fa.set_block_style()
for key, value in d. items():
try:
if '{' in value:
d[key] = ruamel.yaml.scalarstring.DoubleQuotedScalarString(value)
except TypeError:
pass
block_style(value)
elif isinstance(d, list):
d.fa.set_block_style()
for elem in d:
block_style(elem)
yaml = ruamel.yaml.YAML()
with open('input.json') as fp:
data = yaml.load(fp)
block_style(data)
yaml.dump(data, sys.stdout)
给出:
- job-template:
name: "{name}_job"
description: job description
project-type: multibranch
number-to-keep: 30
days-to-keep: 30
scm:
- git:
url: "{git_url}"
以上对于Python2和Python3同样有效
'{'
的额外代码测试是对不能表示为普通标量的字符串强制使用双引号。默认情况下,如果不需要使用YAML双引号标量中可用的额外转义序列来表示字符串,则ruamel.yaml
将使用单引号标量。