Aller au contenu
jsonbeautifiers
Français

YAML en JSON

Flux multi-documents, et un interrupteur pour le piège des booléens de YAML 1.1.

YAML
JSON

Rien de ce que vous collez ne quitte votre navigateur. La liste d’autorisation connect-src en fait une garantie du navigateur plutôt qu’une promesse. Vérifiez-le vous-même

Convertissez du YAML en JSON, avec prise en charge multi-documents et un interrupteur pour les règles de typage qui causent le plus de confusion.

C’est dans ce sens que les choses tournent mal, et presque tout se ramène à la version de YAML qu’implémentent vos autres outils.

Le problème norvégien, démontré

En YAML 1.1, les mots nus no, yes, on, off, y et n sont des booléens. Une liste de pays contenant NO pour la Norvège s’analyse donc en false. En YAML 1.2, ce sont des chaînes ordinaires.

Cela compte parce que la fracture traverse tout l’écosystème. PyYAML, Psych en Ruby et plusieurs outils anciens implémentent 1.1. js-yaml, yaml.v3 en Go et la plupart des analyseurs modernes implémentent 1.2. Le même fichier veut dire des choses différentes selon qui le lit.

Vous pouvez changer les règles de typage ici et voir une valeur changer sous vos yeux. Mesuré avec js-yaml 5.4.1 : `a: no` donne la chaîne "no" en YAML 1.2 et le booléen false en YAML 1.1. Même en mode 1.2, cet outil vous prévient lorsqu’il voit un no ou un yes sans guillemets, car l’outil suivant de votre chaîne pourrait ne pas être d’accord avec lui.

Les autres choses que YAML a et que JSON n’a pas

Commentaires
Perdus, définitivement. JSON n’a pas de syntaxe de commentaire. Si vous maintenez le YAML à la main, cette conversion est à sens unique.
Ancres et alias
Développés sur place. Un document utilisant une ancre cinq fois devient cinq copies dans le JSON, qui peut être nettement plus volumineux.
Horodatages
YAML résout les scalaires en forme de date en véritables dates. JSON n’a pas de type date : elles sont donc écrites en chaînes ISO 8601. Choisissez les règles de typage JSON pour qu’elles restent de simples chaînes dès le départ.
Clés non textuelles
YAML autorise un nombre, voire une séquence, comme clé de mapping. JSON non : elles sont converties en chaînes.
.inf et .nan
Aucun équivalent JSON, ils deviennent donc null.
Documents multiples
Un flux séparé par --- contient plusieurs documents. Par défaut le premier est converti et on vous signale qu’il y en avait d’autres ; activez « tous les documents » pour obtenir un tableau.

Tabulations

YAML interdit les tabulations pour l’indentation, absolument et sans exception. C’est l’erreur YAML la plus fréquente qui soit, et elle arrive parce qu’un éditeur est configuré pour insérer des tabulations. Cet outil vous avertit des tabulations avant même d’essayer d’analyser, car le message que produit alors n’importe quel analyseur n’aide en rien.

How to do this in code

Convertir en code, et l’argument de sécurité qui va avec.

py Python

PyYAML implémente YAML 1.1 : c’est donc là que "no" devient 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 implémente YAML 1.2, donc ici "no" reste une chaîne.

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

Questions fréquentes

Pourquoi ma valeur est-elle devenue true ou false ?
Vous la lisez avec un analyseur YAML 1.1, où no, yes, on, off, y et n sont des booléens. Mettez la valeur entre guillemets, ou utilisez un analyseur YAML 1.2. Changez les règles de typage ci-dessus pour voir la différence sur votre propre document.
Où sont passés mes commentaires ?
JSON n’a pas de commentaires, ils sont donc supprimés. Il n’y a pas de contournement. Si le YAML est un fichier que vous maintenez, gardez-le comme source de vérité et générez le JSON à partir de lui.
Pourquoi yaml.load est-il dangereux en Python ?
Parce qu’il peut instancier des objets Python arbitraires à partir de balises du document, ce qui rend l’analyse d’un YAML non fiable équivalente à son exécution. Utilisez toujours safe_load.