Что делает один восклицательный знак в YAML? - PullRequest
35 голосов
/ 12 марта 2012

Я работаю с библиотекой 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 Ответ

47 голосов
/ 14 марта 2012

Это "!"это "неспецифический тег".

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

При явном указании свойства!!Затем узел будет преобразован в «ванильную» последовательность, отображение или строку в соответствии с его видом.

Взгляните здесь на тег «грамматика»:

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 из scanner.c (LibYAML):

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

Строка 2146 из Scanner.cs (YamlDotNet):

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

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

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

...