Vai al contenuto
jsonbeautifiers
Italiano

YAML in JSON

Stream multi-documento e un interruttore per la trappola dei booleani di YAML 1.1.

YAML
JSON

Nulla di ciò che incolli lascia il tuo browser. L’allowlist connect-src ne fa una garanzia del browser anziché una promessa. Verificalo tu stesso

Converti YAML in JSON, con supporto multi-documento e un interruttore per le regole di tipizzazione che creano più confusione.

È in questa direzione che le cose vanno storte, e quasi tutto si riduce a quale versione di YAML implementano gli altri tuoi strumenti.

Il problema della Norvegia, dimostrato

In YAML 1.1 le parole nude no, yes, on, off, y e n sono booleani. Quindi un elenco di paesi che contiene NO per la Norvegia viene letto come false. In YAML 1.2 sono normali stringhe.

La cosa conta perché la frattura attraversa tutto l’ecosistema. PyYAML, Psych in Ruby e diversi strumenti più vecchi implementano 1.1. js-yaml, yaml.v3 in Go e quasi tutti i parser moderni implementano 1.2. Lo stesso file significa cose diverse a seconda di chi lo legge.

Qui puoi cambiare le regole di tipizzazione e vedere un valore cambiare davanti ai tuoi occhi. Misurato con js-yaml 5.4.1: `a: no` dà la stringa "no" con YAML 1.2 e il booleano false con YAML 1.1. Anche in modalità 1.2, questo strumento avvisa quando vede un no o un yes senza virgolette, perché lo strumento successivo nella tua catena potrebbe non essere d’accordo.

Le altre cose che YAML ha e JSON no

Commenti
Persi, per sempre. JSON non ha una sintassi per i commenti. Se curi lo YAML a mano, questa è una conversione a senso unico.
Ancore e alias
Vengono espansi sul posto. Un documento che usa un’ancora cinque volte diventa cinque copie nel JSON, che può risultare parecchio più grande.
Timestamp
YAML risolve gli scalari a forma di data in date vere. JSON non ha un tipo data, quindi vengono scritte come stringhe ISO 8601. Scegli le regole di tipizzazione JSON perché restino semplici stringhe fin dall’inizio.
Chiavi non testuali
YAML consente un numero o perfino una sequenza come chiave di mapping. JSON no, quindi vengono convertite in stringhe.
.inf e .nan
Nessun equivalente JSON, quindi diventano null.
Documenti multipli
Uno stream separato da --- contiene più documenti. Per impostazione predefinita viene convertito il primo e ti viene detto che ce n’erano altri; attiva «tutti i documenti» per ottenere un array.

Tabulazioni

YAML vieta le tabulazioni per l’indentazione, in modo assoluto e senza eccezioni. È l’errore YAML più comune che esista, e capita perché un editor è configurato per inserire tabulazioni. Questo strumento avvisa delle tabulazioni prima ancora di provare ad analizzare, dato che il messaggio che ne esce da qualunque parser non aiuta affatto.

How to do this in code

Convertire nel codice, con l’argomento di sicurezza che ne fa parte.

py Python

PyYAML implementa YAML 1.1, quindi è qui che "no" diventa False.

import yaml, json

# safe_load, never load. yaml.load can construct arbitrary Python
# objects and has been a real remote-code-execution vector.
data = yaml.safe_load(text)
print(json.dumps(data, indent=2, default=str))

# default=str handles the datetime objects PyYAML produces for
# date-shaped scalars, which json.dumps otherwise refuses.
sh Shell
yq -o=json eval . input.yaml > output.json

# Every document of a multi-document stream
yq -o=json eval-all '[.]' input.yaml
js JavaScript

js-yaml implementa YAML 1.2, quindi qui "no" resta una stringa.

import { load, loadAll } from 'js-yaml';

const data = load(text);              // YAML 1.2 core schema
const docs = loadAll(text);           // multi-document stream
go Go
import "gopkg.in/yaml.v3"

var v any
if err := yaml.Unmarshal(data, &v); err != nil { return err }
out, _ := json.MarshalIndent(v, "", "  ")

Domande frequenti

Perché il mio valore è diventato true o false?
Lo stai leggendo con un parser YAML 1.1, dove no, yes, on, off, y e n sono booleani. Metti il valore tra virgolette, oppure usa un parser YAML 1.2. Cambia le regole di tipizzazione qui sopra per vedere la differenza sul tuo documento.
Dove sono finiti i miei commenti?
JSON non ha commenti, quindi vengono eliminati. Non c’è modo di aggirarlo. Se lo YAML è un file che curi tu, tienilo come fonte di verità e genera il JSON da lì.
Perché yaml.load è insicuro in Python?
Perché può istanziare oggetti Python arbitrari a partire dai tag nel documento, il che rende analizzare YAML non fidato equivalente a eseguirlo. Usa sempre safe_load.