2012-03-12 13 views
28

Sto lavorando con la libreria YamlDotNet e sto ottenendo questo errore durante il caricamento di un file YAML: tagCosa fa un singolo punto esclamativo in YAML?

Durante l'analisi di un tag, non ha trovato previsto URI.

Il file YAML dovrebbe essere ben formato perché viene right from RoR. L'errore sembra essere innescato da questo codice:

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

Io non sono un esperto, ma vedo dal spec YAML che è possibile utilizzare un punto esclamativo per indicare un oggetto personalizzato/tipo, e due punti esclamativi per indicare un tipo predefinito esplicito.

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

Tuttavia, non è stato possibile trovare alcun riferimento a un punto esclamativo utilizzato come sopra. Che cosa significa e perché la libreria YAML che utilizzo non sembra in grado di analizzarla? Si noti che se rimuovo quei punti esclamativi, il file viene analizzato correttamente.

risposta

36

Che "!" è il "tag non specifico".

YAML specification 1.2 soggiorni (anche 1.1): “!”

esplicitando una proprietà tag non specifico, il nodo sarebbero quindi essere risolti in un “vanilla” sequenza, mappatura, o una stringa, secondo il suo genere.

Date un'occhiata here al tag "grammatica":

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"). 

Perché YamlDotNet gettando un errore? Non posso essere sicuro al 100%, ma penso che tu abbia trovato un bug.

YamlDotNet è una porta di LibYAML, quindi è facile confrontare le fonti.

Linea 2635 scanner.c (LibYAML):

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

Linea 2146 di Scanner.cs (YamlDotNet):

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

Lo so, entrambi sembra molto simile, ma a questo punto length è 1 e tag.Length è 0. Il codice originale C si occupa del "!" Iniziale (intera lunghezza) ma C# non lo fa (solo il tag "nome" lunghezza).

Archiviare un problema nel progetto.

+0

Commentare il controllo sembra risolvere il problema, ma non ho idea del suo effetto su altri costrutti. Comunque ho presentato un bug al progetto. –

+1

equivale a racchiudere l'intera stringa tra virgolette anziché utilizzare il singolo punto esclamativo in primo piano? – Magne

+1

i collegamenti alle specifiche dovrebbero essere corretti (1.1 - collegamento a 1.2, 1.2 - collegamenti a 1.1) – kovpack