Что делает один восклицательный знак в YAML?

Я работаю с библиотекой YamlDotNet, и я получаю эту ошибку при загрузке файла YAML:

При анализе тега не найден ожидаемый URI-тег.

Файл YAML должен быть хорошо сформирован, потому что он поставляется прямо из RoR. Кажется, что ошибка вызвана этой ошибкой:

formats:
  default: ! '%d-%m-%Y'
  long: ! '%d %B, %Y'
  short: ! '%d %b'

Я не эксперт, но я вижу из спецификации YAML, что вы можете использовать восклицательный знак для указания пользовательского объекта/типа и двух восклицательных знаков, чтобы указать явный встроенный тип.

obj1: !custom # whatever
obj2: !!str "My string"

Однако мне не удалось найти ссылку на восклицательный знак, использованный выше. Что это значит, и почему библиотека YAML, которую я использую, не может ее проанализировать? Обратите внимание, что если я удалю эти восклицательные знаки, файл будет отлично разбираться.

Ответ 1

Это "!" является "неспецифическим тегом".

спецификация YAML 1.2 остается (также 1.1):

Явным образом указывая "!" неспецифическое свойство тега, nodeзатем будет разрешено последовательность "vanilla", отображение или строку, в соответствии с его видом.

Посмотрите здесь в тег "grammar":

none    : Unspecified tag (automatically resolved by application).
'!'     : Non-specific tag (by default, "!!map"/"!!seq"/"!!str").
'!foo'  : Primary (by convention, means a local "!foo" tag).
'!!foo' : Secondary (by convention, means "tag:yaml.org,2002:foo").
'!h!foo': Requires "%TAG !h! <prefix>" (and then means "<prefix>foo").
'!<foo>': Verbatim tag (always means "foo").

Почему YamlDotNet выбрасывает ошибку? Я не могу быть на 100% уверен, но, думаю, вы нашли ошибку.

YamlDotNet - это порт LibYAML, поэтому легко сравнивать источники.

Строка 2635 сканера .c(LibYAML):

/* Check if the tag is non-empty. */
if (!length) {

Линия 2146 сканера .cs(YamlDotNet):

// Check if the tag is non-empty.
if (tag.Length == 0)

Я знаю, оба выглядят очень похожими, но на данный момент length равно 1 и tag.Length равно 0. Исходный код C заботится об исходном "!" (целая длина), но С# не делает этого (просто длина тега "name" ).

Задайте проблему проекту.