我需要在我的资产之间存储一些元信息和依赖关系,在我可以用来做一些验证的文件中。
以JSON为例,我的元数据文件看起来像这样(/publish/path/metadata/poster.json
):
{
'created_by': 'John',
'creation_date': '12112018',
'version': '005',
'creator_comments': 'Updated to latest published images for Poppy',
'path_to_file': '/publish/path/images/poster.png',
'dependencies': [
'/publish/path/metadata/poppy.json',
'/publish/path/metadata/dwarf.json',
'/publish/path/metadata/giant.json'
]
}
和(/publish/path/metadata/poppy.json
):
{
'created_by': 'Daug',
'creation_date': '12102018',
'version': '003',
'creator_comments': 'Poppy is more red on top',
'path_to_file': '/publish/path/images/poppy.png',
'dependencies': [
'/publish/path/metadata/poppy_drawing.json',
'/publish/path/metadata/poppy_effect.json'
]
}
我正在寻找一种最合适的文件格式
您认为哪种方式最适合我的用例?
答案 0 :(得分:1)
JSON,YAML和XML都是流行的文件格式,有一些优点和缺点。还有其他文件格式,例如TOML,INI files等。以下是JSON,YAML和XML的概述:
<强> JSON 强>
\n
package.json
<强> YAML 强>
<强> XML 强>
<强>摘要强>
对于您的查看者要求,您可以使用模式来标识文件链接,然后修改现有查看器以在存在时添加链接。当然,您也可以从头开始创建自己的。
根据您的要求,JSON和YAML似乎是最合适和最受欢迎的。好处是有许多通用工具可以来回转换JSON和YAML。自动转换并不像其他文件格式那样普遍。
答案 1 :(得分:0)
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是否为美国或DDMMYYYY中使用的MMDDYYYY,因为更多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。