YAML 旨在包含人类可读的数据形式,例如您的数据,(但在 YAML 中有多种表示数据的方式不太可读)
XML,我已经看到将其描述为具有二进制的可读性和 ASCII 的低效率。
JSON 的双引号过多,无法突出其实际数据。如果你想手动编辑数据,你真的必须小心数组和对象中的尾随逗号。
当然没有直接支持您的格式的查看器或浏览器,但如果您从 JSON 开始,则可以编写一个 JavaScript 程序,通过超链接正确显示每个数据集。当您通过浏览器内置的 de DOMparser 开始使用 XML 时,您也可以这样做。 javascript 中也有 YAML 解析器,可以对基于 YAML 的数据执行相同的操作,但必须安装这些解析器并将其加载到浏览器中。
如果您不想使用 javascript 编程,我会选择将数据放入 YAML 并有一个 Python 程序(递归地)查看所有单独的 YAML 文件并从中生成 HTML,包括正确的超链接(到依赖项的 HTML“版本”)和图像的链接,或图像的适当显示。如果包含 YAML 文档的相应文件具有较新的时间戳,则使程序足够智能以仅(重新)生成 HTML。
这类似于一些从标记生成静态视图的博客系统的工作方式。而且由于您无论如何都想使用 Python 处理数据,因此您应该能够重用您编写的一些代码。
你应该让你的/publish/path/metadata/poster.yaml:
created_by: John
creation_date: 2018-11-12
version: 005
creator_comments: Updated to latest published images for Poppy
path_to_file: /publish/path/images/poster.png
dependencies:
- /publish/path/metadata/poppy.yaml
- /publish/path/metadata/dwarf.yaml
- /publish/path/metadata/giant.yaml
正如您所见,您不必将日期写为字符串,YAML 直接支持 YYYY-MM-DD 格式(不清楚您的 creation_date 是美国使用的 MMDDYYYY 还是 DDMMYYYY 更多wideley 用于其他英语国家)。您如何在 HTML 中显示日期当然是您的偏好。
对于您的 YAML,您应该遵守最新规范(2009 年的 1.2)并使用 ruamel.yaml(免责声明:我是该软件包的作者)。如果你选择 YAML 1.1(在这种情况下你可以使用 PyYAML),你必须引用并将你的版本定义为 PyYAML 的标量字符串,否则将 version: 015 解释为数字 13。ruamel.yaml 也正确地往返和用前导零再次写入此类整数。如果您的版本包含非数字数据,则 YAML 会自动将其加载为字符串(无需引用)。
对于转储 HTML,有很多选择,使用一些库来创建树形结构,然后转储具有无法生成无效 HTML 的优点。但即使您“手动”生成 HTML,也应该相对快速地调试输出。
转换程序当然也可以检查所有引用是否存在,如果不存在则警告您。
执行上述操作的简单程序(输出的 HTML 不太好看):
from datetime import date
from pathlib import Path
from ruamel.yaml import YAML
from ruamel.yaml.scalarint import ScalarInt
yaml = YAML()
def convert_data(d, fp, level=0):
"""recursively write a loaded YAML document as HTML"""
if isinstance(d, dict):
print('<table>', file=fp)
for k in d:
print('<tr><td>', file=fp)
convert_data(k, fp, level=level+1)
print('</td><td>', file=fp)
v = d[k]
convert_data(v, fp, level=level+1)
print('</td></tr>', file=fp)
print('</table>', file=fp)
return
if isinstance(d, list):
print('<ul>', file=fp)
for elem in d:
print('<li>', file=fp)
convert_data(elem, fp, level=level+1)
print('</li>', file=fp)
print('</ul>', file=fp)
return
if isinstance(d, str) and d and d[0] == '/':
if d.endswith('.yaml'):
h = Path(d).with_suffix('.html')
print('<a href="{}">{}</a>'.format(h, d), file=fp)
return
if d.endswith('.png'):
print('<img src="{}">'.format(d), file=fp)
return
if isinstance(d, ScalarInt):
if d._width is not None:
# integer with leading zeros
print('{:0{}d}'.format(d, d._width), file=fp)
return
if isinstance(d, date):
# print the date in DDMMYYYY format
print('{:%d%m%Y}'.format(d), file=fp)
return
print(d, file=fp)
def convert_file(yaml_file, html_file):
data = yaml.load(yaml_file)
with html_file.open('w') as fp:
print('<html>\n<body>', file=fp)
convert_data(data, fp)
print('</body>\n</html>', file=fp)
def main():
for yaml_file in Path('.').glob('*.yaml'):
html_file = yaml_file.with_suffix('.html')
if True or not html_file.exists() or \
html_file.stat().st_mtime < yaml_file.stat().st_mtime:
convert_file(yaml_file, html_file)
if __name__ == '__main__':
main()
您当然可以通过使用标签(!link /publish/path/metadata/poppy.yaml 和 !img /publish/path/images/poster.png 来明确链接和图像,并为这些标签创建带有构造函数的类,然后转储适当的 HTML。但这并不一定会给您提供更好的可读性 YAML。