YAML ( / ˈ j æ m ə l / ; см. § История и название) —язык сериализации данных,удобный для чтения человеком . Он обычно используется дляфайлов конфигурациии в приложениях, где данные хранятся или передаются. YAML нацелен на многие из тех же приложений связи, что иExtensible Markup Language(XML), но имеет минимальный синтаксис, который намеренно отличается отStandard Generalized Markup Language(SGML).[3]Он используетPythonдля указания вложенности[3]и не требует кавычек вокруг большинства строковых значений (он также поддерживаетстильJSONисмешанный в одном файле).[4][...]
{...}
Пользовательские типы данных разрешены, но YAML изначально кодирует скаляры (такие как строки , целые числа и числа с плавающей точкой ), списки и ассоциативные массивы (также известные как карты, словари или хэши). Эти типы данных основаны на языке программирования Perl , хотя все широко используемые языки программирования высокого уровня имеют очень похожие концепции. [5] [6] [7] Синтаксис с двоеточием в центре, используемый для выражения пар ключ-значение , вдохновлен заголовками электронной почты , как определено в RFC 822, а разделитель документов ---
заимствован из MIME ( RFC 2046). Escape-последовательности повторно используются из C , а перенос пробелов для многострочных строк вдохновлен HTML . Списки и хэши могут содержать вложенные списки и хэши, образуя древовидную структуру ; произвольные графы могут быть представлены с помощью псевдонимов YAML (аналогично XML в SOAP ). [3] YAML предназначен для чтения и записи в потоках, эта функция вдохновлена SAX . [3]
Поддержка чтения и записи YAML доступна для многих языков программирования. [8] Некоторые редакторы исходного кода, такие как Vim , [9] Emacs , [10] и различные интегрированные среды разработки [11] [12] [13] имеют функции, которые упрощают редактирование YAML, такие как сворачивание вложенных структур или автоматическое выделение синтаксических ошибок.
Официально рекомендуемое расширение имени файла для файлов YAML существует .yaml
с 2006 года. [14] В 2024 году тип MIME application/yaml
был окончательно утвержден. [1]
YAML ( / ˈ j æ m əl / , рифмуется с camel [4] ) был впервые предложен Кларком Эвансом в 2001 году [15] , который разработал его совместно с Инги Дёт Нет [16] и Ореном Бен-Кики. [16] Первоначально YAML, как говорили, означало Yet Another Markup Language [ 17] , потому что он был выпущен в эпоху, когда наблюдалось распространение языков разметки для представления и связи (HTML, XML, SGML и т. д.). Его первоначальное название было задумано как ироничная ссылка [18] на технологический ландшафт, ссылаясь на его цель как языка разметки с помощью конструкции yet another , но затем он был перепрофилирован в YAML Ain't Markup Language , рекурсивный акроним , чтобы обозначить его цель как ориентированную на данные, а не разметку документов.
Шпаргалка и полная спецификация доступны на официальном сайте. [19] Ниже приведен краткий обзор основных элементов.
YAML принимает весь набор символов Unicode, за исключением некоторых управляющих символов , и может быть закодирован в любой из кодировок UTF-8 , UTF-16 или UTF-32 . (Хотя UTF-32 не является обязательным, он необходим для совместимости с JSON анализатора .) [20]
#
), могут начинаться в любом месте строки и продолжаться до конца строки. Комментарии должны быть отделены от других токенов пробелами. [22] Если внутри строки появляются символы #, то они являются #
литералами знака номера ( ).-
, по одному члену в строке.[...]
), разделив каждую запись запятой .http://www.wikipedia.org
можно было представлять без необходимости заключать в кавычки.{...}
), при этом ключи отделяются от значений двоеточием, а записи разделяются запятыми (пробелы не требуются для сохранения совместимости с JSON)."
) или одинарные ( '
) кавычки.\
). Согласно документации, поддерживается только восьмеричная управляющая последовательность \0
.''
), обозначающая саму одинарную кавычку, как в 'don''t'
.|
) или сворачивания ( >
) новых строк.---
)....
) по желанию завершают документ в потоке.&
, а затем обозначаются звездочкой ( *
).!!
), за которым следует строка, которую можно развернуть в URI.%
), за которым следует имя и разделенные пробелами параметры. В YAML 1.1 определены две директивы:В традиционном блочном формате для начала нового элемента в списке используется дефис+пробел.
--- # Любимые фильмы - Касабланка - К северу через северо-запад - Человек, которого не было
Необязательный встроенный формат разделяется запятой+пробелом и заключается в скобки (аналогично JSON ). [23]
--- # Список покупок [ молоко , тыквенный пирог , яйца , сок ]
Ключи отделяются от значений двоеточием+пробелом. Отступные блоки, распространенные в файлах данных YAML, используют отступы и новые строки для разделения пар ключ/значение. Встроенные блоки, распространенные в потоках данных YAML, используют запятую+пробел для разделения пар ключ/значение между фигурными скобками.
--- # Отступ Имя блока : Джон Смит возраст : 33 --- # Встроенный блок { имя : Джон Смит , возраст : 33 }
Строки не требуют кавычек. Существует два способа записи многострочных строк: один с сохранением новых строк (используя |
символ ), а другой сворачивает новые строки (используя >
символ ), за обоими следует символ новой строки.
data : | Однажды жил высокий мужчина из Илинга , который сел в автобус до Дарджилинга. На двери было написано : «Пожалуйста, не садитесь на пол». Поэтому он осторожно сел на потолок.
По умолчанию начальный отступ (первой строки) и конечные пробелы удаляются, хотя можно явно указать иное поведение.
данные : > Перенесенный текст будет сложен в один абзац Пустые строки обозначают разрывы абзацев.
Свернутый текст преобразует символы новой строки в пробелы и удаляет начальные пробелы.
--- # The Smiths - { имя : Джон Смит , возраст : 33 } - имя : Мэри Смит возраст : 27 - [ имя , возраст ]: [ Рэй Смит , 4 ] # последовательности в качестве ключей поддерживаются --- # Люди, по полу мужчины : [ Джон Смит , Билл Джонс ] женщины : - Мэри Смит - Сьюзан Уильямс
Объекты и списки являются важными компонентами yaml и могут смешиваться. Первый пример — список объектов «ключ-значение», все люди из семьи Смит. Второй пример перечисляет их по полу; это объект «ключ-значение», содержащий два списка.
Две особенности, которые отличают YAML от возможностей других языков сериализации данных, — это структуры [24] и типизация данных.
Структуры YAML позволяют хранить несколько документов в одном файле, использовать ссылки для повторяющихся узлов и использовать произвольные узлы в качестве ключей. [24]
Для ясности, компактности и избежания ошибок ввода данных YAML предоставляет якоря узлов (используя &
) и ссылки (используя *
). Ссылки на якорь работают для всех типов данных (см. ссылку ship-to в примере ниже).
Ниже приведен пример очереди в секвенсоре инструментов, в котором два шага упоминаются без их полного описания.
--- # Протоколы секвенсора для лазерной хирургии глаза - шаг : &id001 # определяет метку привязки &id001 инструмент : Lasik 2000 Энергия импульса : 5,4 Длительность импульса : 12 повторений : 1000 Размер пятна : 1 мм - шаг : &id002 инструмент : Lasik 2000 импульсЭнергия : 5,0 импульсДлительность : 10 повторений : 500 Размер пятна : 2 мм - Инструмент1 : *id001 # относится к первому шагу (с привязкой &id001) - Инструмент2 : *id002 # относится ко второму шагу
Явная типизация данных редко встречается в большинстве документов YAML, поскольку YAML автоматически определяет простые типы. Типы данных можно разделить на три категории: основные, определенные и определяемые пользователем. Основные — это те, которые, как ожидается, будут существовать в любом парсере (например, числа с плавающей точкой, целые числа, строки, списки, карты, ...). Многие более сложные типы данных, такие как двоичные данные, определены в спецификации YAML, но не поддерживаются во всех реализациях. Наконец, YAML определяет способ локального расширения определений типов данных для размещения определяемых пользователем классов, структур или примитивов (например, числа с плавающей точкой четверной точности).
YAML автоматически определяет тип данных сущности, но иногда требуется явно указать тип данных. Наиболее распространенная ситуация — когда строка из одного слова, которая выглядит как число, логическое значение или тег, требует устранения неоднозначности путем заключения ее в кавычки или использования явного тега типа данных.
--- a : 123 # целое число b : "123" # строка, неоднозначность устраняется кавычками c : 123.0 # число с плавающей точкой d : !!float 123 # также число с плавающей точкой через явный тип данных с префиксом (!!) e : !!str 123 # строка, неоднозначность устраняется явным типом f : !!str Да # строка через явный тип g : Да # логическое значение True (yaml1.1), строка "Yes" (yaml1.2) h : Да у нас нет бананов # строка, неоднозначность "Yes" и "No" устраняется контекстом.
Не каждая реализация YAML имеет все типы данных, определенные спецификацией. Эти встроенные типы используют префикс с двойным восклицательным знаком ( !!
). Особенно интересными, не показанными здесь, являются наборы, упорядоченные карты, временные метки и шестнадцатеричные данные. Вот пример двоичных данных, закодированных в base64 .
--- картинка : !!двоичный | R0lGODdhDQAIAIAAAAAAANn Z2SwAAAAADQAIAAACF4SDGQ ar3xxbJ9p0qa7R0YxwzaFME 1IAADs=
Многие реализации YAML могут поддерживать пользовательские типы данных для сериализации объектов. Локальные типы данных не являются универсальными типами данных, но определяются в приложении с помощью библиотеки парсера YAML. Локальные типы данных используют один восклицательный знак ( !
).
Иерархия структуры данных поддерживается за счет отступов контура.
--- квитанция : Oz-Ware Дата счета-фактуры покупки : 2012-08-06 Клиент : Имя : Дороти Имя_фамилия : Гейл items : - part_no : A4786 descrip : Ведро для воды (наполненное) цена : 1.47 количество : 4 - part_no : E1628 descrip : Туфли на высоком каблуке "Рубин" размер : 8 цена : 133.7 количество : 1 счет-кому : &id001 улица : | 123 Tornado Alley Suite 16 город : East Centerville штат : KS получатель : *id001 specialDelivery : > Идите по дороге из желтого кирпича в Изумрудный город. Не обращайте внимания на человека за занавеской. ...
Обратите внимание, что строки не требуют заключения в кавычки. Конкретное количество пробелов в отступе неважно, пока параллельные элементы имеют одинаковое выравнивание по левому краю, а иерархически вложенные элементы имеют больший отступ. В этом образце документа определяется ассоциативный массив с 7 ключами верхнего уровня: один из ключей, «items», содержит список из 2 элементов, каждый элемент которого сам по себе является ассоциативным массивом с различными ключами. Отображаются реляционные данные и удаление избыточности: содержимое ассоциативного массива «ship-to» копируется из содержимого ассоциативного массива «bill-to», как указано метками привязки ( &
) и ссылки ( *
). Для удобства чтения можно добавлять необязательные пустые строки. Несколько документов могут существовать в одном файле/потоке и разделяться ---
. Необязательный параметр ...
может использоваться в конце файла (полезно для сигнализации об окончании в потоковых сообщениях без закрытия канала).
Поскольку YAML в первую очередь полагается на отступы контуров для структуры, он особенно устойчив к столкновению разделителей . Нечувствительность YAML к кавычкам и фигурным скобкам в скалярных значениях означает, что можно встраивать XML, JSON или даже YAML-документы внутрь YAML-документа, просто сделав отступ в блочном литерале (используя |
или >
):
--- пример : > HTML переходит в YAML без изменения сообщения : | <blockquote style="font: italic 1em serif"> <p>"Три всегда больше двух, даже для больших значений двух"</p> <p>--Автор неизвестен</p> </blockquote> дата : 2007-06-01
YAML можно поместить в JSON, заключив в кавычки и экранировав все внутренние кавычки. YAML можно поместить в XML, экранировав зарезервированные символы ( <
, >
, &
, '
, "
) и преобразовав пробелы, или поместив его в раздел CDATA .
В отличие от JSON, который может представлять данные только в иерархической модели, где каждый дочерний узел имеет одного родителя, YAML также предлагает простую реляционную схему, которая позволяет ссылаться на повторы идентичных данных из двух или более точек дерева, а не вводить их избыточно в этих точках. Это похоже на средство IDREF, встроенное в XML. [25] Затем анализатор YAML расширяет эти ссылки в полностью заполненные структуры данных, которые они подразумевают при чтении, поэтому любая программа, использующая анализатор, не должна знать о реляционной модели кодирования, в отличие от процессоров XML, которые не расширяют ссылки. Это расширение может улучшить читаемость, одновременно уменьшая ошибки ввода данных в файлах конфигурации или протоколах обработки, где многие параметры остаются неизменными в последовательной серии записей, в то время как только некоторые из них изменяются. Примером может служить то, что записи «ship-to» и «bill-to» в счете-фактуре почти всегда представляют собой одни и те же данные.
YAML ориентирован на строки, поэтому часто бывает просто преобразовать неструктурированный вывод существующих программ в формат YAML, сохранив при этом большую часть внешнего вида исходного документа. Поскольку нет закрывающих тегов, фигурных скобок или кавычек для балансировки, обычно легко генерировать правильно сформированный YAML непосредственно из распределенных операторов печати в простых программах. Аналогично, разделители пробелов облегчают быструю и грязную фильтрацию файлов YAML с использованием ориентированных на строки команд в grep, AWK, Perl, Ruby и Python.
В частности, в отличие от языков разметки, фрагменты последовательных строк YAML, как правило, сами являются хорошо сформированными документами YAML. Это позволяет очень легко писать парсеры, которым не нужно обрабатывать документ целиком (например, балансируя открывающие и закрывающие теги и перемещаясь по кавычкам и экранированным символам) перед тем, как они начнут извлекать определенные записи внутри. Это свойство особенно целесообразно при итерации в одном проходе без сохранения состояния по записям в файле, вся структура данных которого слишком велика для хранения в памяти, или для которого восстановление всей структуры для извлечения одного элемента было бы непомерно дорогим.
Противореча интуиции, хотя его отступное разграничение может показаться усложняющим глубоко вложенные иерархии, YAML обрабатывает отступы размером с один пробел, и это может обеспечить лучшее сжатие, чем языки разметки. Кроме того, чрезвычайно глубоких отступов можно полностью избежать, либо: 1) вернувшись к «встроенному стилю» (т. е. JSON-подобному формату) без отступов; или 2) используя реляционные якоря для разворачивания иерархии в плоскую форму, которую анализатор YAML прозрачно восстановит в полную структуру данных. [26]
YAML — это просто язык представления данных, и поэтому в нем нет исполняемых команд. Хотя валидация и безопасный синтаксический анализ по своей сути возможны в любом языке данных, реализация — это такая печально известная ловушка, что отсутствие в YAML связанного командного языка может быть относительным преимуществом безопасности.
Однако YAML допускает теги, специфичные для языка, так что произвольные локальные объекты могут быть созданы парсером, который поддерживает эти теги. Любой парсер YAML, который позволяет выполнять сложную инстанциацию объектов, открывает потенциал для атаки с внедрением. Парсеры Perl, которые позволяют загружать объекты произвольных классов, создают так называемые «благословенные» значения. Использование этих значений может вызвать неожиданное поведение, например, если класс использует перегруженные операторы. Это может привести к выполнению произвольного кода Perl. [27] [ ненадежный источник? ]
Аналогичная ситуация для парсеров Python или Ruby. Согласно документации PyYAML: [28]
Обратите внимание, что возможность создания произвольного объекта Python может быть опасной, если вы получаете документ YAML из ненадежного источника, например из Интернета. Функция
yaml.safe_load
ограничивает эту возможность простыми объектами Python, такими как целые числа или списки. [...]PyYAML позволяет вам создавать объекты Python любого типа. Даже экземпляры классов Python могут быть созданы с использованием
!!python/object
тега.
Спецификация YAML определяет документ экземпляра как «Презентацию» или «поток символов». [29] Основными логическими структурами в документе экземпляра YAML являются скаляры, последовательности и отображения. [30] Спецификация YAML также указывает некоторые основные ограничения, которые применяются к этим основным логическим структурам. Например, согласно спецификации, ключи отображения не имеют порядка. В каждом случае, когда порядок узлов имеет значение, должна использоваться последовательность. [31]
Более того, при определении соответствия для процессоров YAML спецификация YAML определяет две основные операции: dump и load . Все процессоры, совместимые с YAML, должны предоставлять по крайней мере одну из этих операций и могут опционально предоставлять обе. [32] Наконец, спецификация YAML определяет информационную модель или «граф представления», который должен быть создан во время обработки для операций dump и load , хотя это представление не обязательно должно быть доступно пользователю через API. [33]
Синтаксис JSON является основой YAML версии 1.2, которая была обнародована с явной целью приведения YAML «в соответствие с JSON как официальным подмножеством». [4] Хотя предыдущие версии YAML не были строго совместимы, [34] несоответствия редко были заметны, и большинство документов JSON могут быть проанализированы некоторыми парсерами YAML, такими как Syck. [35] Это связано с тем, что семантическая структура JSON эквивалентна необязательному «встроенному стилю» написания YAML. Хотя расширенные иерархии могут быть записаны в встроенном стиле, как JSON, это не рекомендуемый стиль YAML, за исключением случаев, когда он способствует ясности.
YAML имеет множество дополнительных функций, отсутствующих в JSON, включая комментарии, расширяемые типы данных, реляционные якоря, строки без кавычек и типы сопоставления, сохраняющие порядок ключей.
Благодаря краткости сериализация и десериализация JSON происходит намного быстрее, чем YAML. [36] [37]
TOML был разработан как усовершенствование формата файла .ini . Минимальное использование символов-индикаторов в YAML выгодно отличается от строгого требования TOML к кавычкам и квадратным скобкам. [ мнение ] Использование значительных отступов в YAML противопоставляется точечной нотации имен ключей и таблиц TOML для передачи той же семантической структуры. Мнения расходятся относительно того, какое соглашение приводит к более читаемым файлам конфигурации. [38] [39]
В YAML отсутствует понятие атрибутов тегов, которые есть в XML. Вместо этого в YAML есть расширяемые объявления типов (включая типы классов для объектов).
Сам YAML не имеет дескрипторов схем документов, определяемых языком XML, которые позволяют, например, документу проводить самопроверку. Однако существует несколько внешних языков дескрипторов схем для YAML (например, Doctrine , Kwalify и Rx), которые выполняют эту роль. Более того, семантика, предоставляемая декларациями типов, определяемых языком YAML, в самом документе YAML часто ослабляет необходимость в валидаторе в простых, общих ситуациях. Кроме того, YAXML, который представляет структуры данных YAML в XML, позволяет применять импортеры схем XML и механизмы вывода, такие как XSLT, к YAML.
Сравнение форматов сериализации данных обеспечивает более полное сравнение YAML с другими форматами сериализации.
Для фиксированных структур данных файлы YAML можно просто сгенерировать с помощью команд печати , которые записывают как данные, так и специфическое оформление YAML. Однако для дампа изменяющихся или сложных иерархических данных предпочтительнее использовать выделенный излучатель YAML . Аналогично, простые файлы YAML (например, пары ключ-значение) легко анализируются с помощью регулярных выражений. Для более сложных или изменяющихся структур данных рекомендуется формальный анализатор YAML.
Существуют излучатели и парсеры YAML для многих популярных языков. Большинство из них написаны на самом родном языке. Некоторые из них являются языковыми привязками библиотеки C libyaml ; они могут работать быстрее. Раньше была еще одна библиотека C, называемая Syck , написанная и осиротевшая по причине того, что повезло : она не поддерживается, нет официального исходного пакета, а веб-сайт был взломан. Следовательно, единственной рекомендуемой библиотекой C является libyaml . Первоначально она была разработана Кириллом Симоновым. В 2018 году разработка была возобновлена новыми сопровождающими Яном Кордаско и Инги Дёт Нет. [40]
У программистов C++ есть выбор между библиотекой C libyaml и библиотекой C++ libyaml-cpp . Обе имеют полностью независимые кодовые базы и совершенно разные API . Библиотека libyaml-cpp по-прежнему имеет основной номер версии 0, что указывает на то, что API может измениться в любой момент, как это и произошло после версии 0.3. Существует реализация, ориентированная на грамматику, написанная на C#, с целью расширения для вложенных элементов. [41]
Некоторые реализации YAML, такие как YAML.pm Perl, загружают весь файл (поток) и анализируют его в массовом порядке . Другие реализации, такие как PyYaml, ленивы и перебирают следующий документ только по запросу. Для очень больших файлов, в которых планируется обрабатывать документы независимо, создание экземпляра всего файла перед обработкой может быть недопустимым. Таким образом, в YAML.pm иногда приходится разбивать файл на документы и анализировать их по отдельности. YAML упрощает это, поскольку для этого требуется просто разбить его на маркер конца документа, который определяется как три точки в начале строки, за которыми следует пробел (и, возможно, комментарий). Этот маркер запрещен в содержимом. [42]
YAML подвергался критике за его значительное количество пробелов , запутанные функции, небезопасные значения по умолчанию, а также его сложную и неоднозначную спецификацию: [43] [44] [45]
Yes
и No
преобразуются в логические значения; номера версий программного обеспечения могут быть преобразованы в числа с плавающей точкой. [43] [46]Ощутимые недостатки и сложность YAML привели к появлению более строгих альтернатив, таких как StrictYAML и NestedText. [46]
/*...*/
комментарии Javascript. Обработка таких пограничных случаев может потребовать легкой предварительной обработки JSON перед анализом как встроенного YAML. См. также [1] Архивировано 29.08.2013 на Wayback Machine .