Наиболее подходящий формат файла для хранения перекрестных ссылок - PullRequest
0 голосов
/ 01 июня 2018

Мне нужно хранить метаинформацию и зависимости между моими активами в файлах, которые я могу использовать для выполнения некоторых проверок в дальнейшем.

Если взять в качестве примера 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'
                         ]
    }

Я ищу формат файла, который был бы наиболее подходящим, чтобы сделать следующее

  1. возможность хранить ссылки на другие файлы
  2. поддерживается библиотеками python, которые могут обрабатывать ссылки
  3. может быть легко прочитано людьми
  4. Поддержка просмотра или браузера, которая позволяет мне просматривать файлы, на которые есть ссылки

Как вы думаете, что лучше всего подходит для моего варианта использования?

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

JSON, YAML и XML - все популярные форматы файлов с некоторыми плюсами и минусами.Существуют и другие форматы файлов, такие как TOML , INI-файлы и другие.Вот краткий обзор JSON, YAML и XML:

JSON

  • Плюсы
    • очень популярны благодаря хорошей поддержке на многих языкахбазовые библиотеки
    • поддерживают схемы через JSON Schema (http://json -schema.org / ) с поддержкой filepath
    • инструменты проверки могут проверять пути к файлам и обсуждаются, например, https://github.com/Julian/jsonschema/issues/98
    • может ссылаться на внешние файлы, как показано в реализации JSON спецификации Swagger
  • Минусы
    • трудно читать несколько строк, так как перевод строки представлен как \n
    • менее идеально подходит для создания вручную
  • Реализации
    • Учетные данные приложения Google
    • NPM package.json
    • Swagger / OpenAPI

YAML

  • Pros
    • популярный и легко читаемый многострочныйзначения, если они у вас есть
    • спецификация доступна: http://yaml.org/spec/1.2/spec.html
    • может ссылаться на внешние файлы, как показано в спецификации Swagger YAML implementation
  • Минусы
    • не отображается в таком количестве базовых языковых библиотек, как JSON
  • Некоторые реализации
    • Файл конфигурации Ruby on Rails
    • Swagger / OpenAPI

XML

  • Плюсы
    • очень большие файлы могут обрабатываться SAX-парсерами, например, ГБ
    • стандартизированная схема: https://www.w3.org/standards/xml/schema
  • Минусы
    • очень многословно и болеетрудно читать
    • Библиотеки XML используются для анализа и создания, например, libxml2.
  • Некоторые реализации
    • RSS / Atom

Сводка

  • JSON, если у вас ограниченный объем данных или нет данных с несколькими строковыми значениями или многострочными значениями, которые людине ожидал прочитать.Это хорошо для файлов конфигурации, потому что внешняя зависимость часто не требуется
  • YAML, если у вас есть больше данных, которые должны быть созданы человеком / отредактированы, включая многострочные значения
  • XML, если у вас естьмного данных, в диапазоне ГБ

По вашему требованию средства просмотра вы можете использовать схему для идентификации ссылки на файл, а затем изменить существующее средство просмотра, чтобы добавить ссылку, когда она есть.Конечно, вы всегда можете создать свой собственный с нуля.

Для ваших требований, как вы заявили, кажется, JSON и YAML будут наиболее подходящими и популярными.Преимущество заключается в том, что существует множество универсальных инструментов для преобразования JSON и YAML туда и обратно.Автоматическое преобразование не так распространено для других форматов файлов.

0 голосов
/ 01 июня 2018

YAML был разработан, чтобы включать в себя удобочитаемые формы данных, такие как ваша, (но есть несколько способов представления данных в YAML, которые не так удобны для чтения)

XML, я видел описанный как имеющийудобочитаемость двоичного кода в сочетании с неэффективностью ASCII.

В JSON слишком много двойных кавычек, чтобы выделить его фактические данные.И если вы хотите редактировать данные вручную, вам действительно нужно позаботиться о том, чтобы конечные запятые в массивах и объектах.


Конечно, нет программы просмотра или просмотра, которая бы напрямую поддерживала ваш формат, но есливы начинаете с JSON, можно написать программу JavaScript, которая отображает каждый набор данных правильно с гиперссылками.Вы можете сделать то же самое, когда начнете с XML через de DOMparser, встроенный в браузер.Есть также синтаксические анализаторы YAML в javascript, которые могут делать то же самое для данных на основе YAML, но их необходимо будет установить и загрузить в браузер.


Если вы не хотите программировать на javascript,Я хотел бы поместить данные в YAML и иметь программу на Python, которая (рекурсивно) просматривает все отдельные файлы YAML и генерирует из них HTML, включая правильные гиперссылки (на «версию» HTML-зависимостей), а также ссылки наизображения, или на месте отображения изображений.Сделайте программу достаточно умной, чтобы (заново) генерировать HTML, только если соответствующий файл, содержащий документ YAML, имеет более новую временную метку.

Это похоже на работу некоторых систем блогов, которые генерируют статические представления из разметки.И поскольку вы все равно хотите обрабатывать данные с помощью 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, как более широко используемым вдругие англоязычные страны).Как вы отображаете даты в своем HTML, конечно, ваши предпочтения.

С вашим YAML вы должны придерживаться последней спецификации (1.2 из 2009) и использовать 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...