Convertisseur JSON vers YAML
Convertit du JSON en YAML et explique chaque guillemet ajouté : les chaînes qui, sans lui, deviendraient booléens, nombres ou dates.
name: deploy
country: 'NO'
startsAt: '12:30'
mode: '0755'
version: '1.10'
released: '2024-01-30'
enabled: 'yes'
script: |-
set -e
npm run build
npm test
replicas: 3
tags:
- web
- edge
Valeurs entre guillemets : 6. Nécessaires en YAML 1.1 seulement : 4. Changez le schéma ci-dessus pour voir la différence.
country1.1 seulement« NO » serait lu comme le booléen false.
startsAt1.1 seulement« 12:30 » serait lu en base 60 comme 750.
mode« 0755 » a un zéro initial : il serait lu comme le nombre 493.
version« 1.10 » serait lu comme le nombre 1.1.
released1.1 seulement« 2024-01-30 » serait lu comme une date et non comme du texte.
enabled1.1 seulement« yes » serait lu comme le booléen true.
Ce que fait cet outil
Il convertit un document JSON en YAML, puis vous dit pourquoi chaque chaîne s’est retrouvée entre guillemets. Cette seconde partie est la raison d’être de l’outil : tout autre convertisseur rend la sortie et vous laisse découvrir plus tard que l’une de vos valeurs n’est plus une chaîne.
La conversion va dans un seul sens. Lire du YAML est un problème bien plus vaste que d’en écrire, et un analyseur YAML partiellement correct est pire que pas d’analyseur du tout : il accepte votre fichier et rend de mauvaises données sans se plaindre. Émettre est un problème borné, et c’est ce sens qui est couvert ici.
Pourquoi un convertisseur doit avoir des avis
JSON dit de quel type est chaque chose. Une chaîne porte des guillemets, un nombre non, et il n’y a pas de troisième possibilité. YAML, lui, décide du type d’une valeur non quotée d’après sa forme : si elle correspond au motif d’un booléen c’est un booléen, si elle correspond à un nombre c’est un nombre, et ce n’est que si elle ne correspond à rien qu’elle reste du texte.
C’est ce qui rend YAML agréable à écrire à la main et ce qui fait de la conversion un jugement. Chaque chaîne de l’entrée doit être confrontée à chaque motif que YAML résout, et mise entre guillemets si elle en satisfait un. Trompez-vous du côté prudent et la sortie est bruyante ; trompez-vous de l’autre et une valeur change de type en silence.
Le problème norvégien et sa parenté
Le cas le plus connu est une liste de codes pays. La Norvège, c’est NO, et en YAML 1.1 le jeton non quoté NO est le booléen false. Un fichier de configuration qui énumère des pays perd la Norvège et gagne un false, et rien nulle part ne signale d’erreur.
Ce n’est pas une règle bizarre isolée mais toute une famille. YAML 1.1 lit y, Y, yes, no, on et off comme des booléens, dans toutes les casses, ce qui attrape un symbole chimique, la position d’un interrupteur et la réponse à une question. Et les résolveurs numériques sont plus étranges encore :
- 12:30 vaut 750. YAML 1.1 lit des chiffres séparés par des deux-points en base 60 : une heure de la journée ou une durée devient un entier.
- 0755 vaut 493. Un zéro initial signifie octal en YAML 1.1 — et en YAML 1.2 le même texte est le décimal 755 : les deux versions divergent sur quel nombre, pas sur le fait que c’en soit un.
- 1.10 vaut 1.1. Un numéro de version en deux parties est un flottant, et le zéro final disparaît. Une dépendance épinglée à 1.10 pointe désormais vers 1.1.
- 2024-01-30 est un objet date et non une chaîne, car YAML 1.1 possède un type horodatage.
- Une chaîne vide vaut null, tout comme les mots nus null, Null, NULL et le tilde.
Aucun de ces cas n’est un bogue de YAML. Ce sont les résolveurs faisant exactement ce qu’ils promettent, sur un texte qui se trouve correspondre. La seule défense est de mettre entre guillemets tout ce qui correspond, ce que fait cet outil et ce dont le panneau des constats rend compte ligne par ligne.
Deux versions, et pourquoi l’ancienne est par défaut
YAML 1.2 est arrivé en 2009 et a supprimé la plupart des résolveurs surprenants. Son schéma de base ne garde que true et false comme booléens, abandonne complètement la base 60 et n’a pas de type horodatage. Sous 1.2, NO, 12:30 et 2024-01-30 sont simplement des chaînes.
Le piège est de savoir ce qui lira réellement votre fichier. PyYAML implémente YAML 1.1, et PyYAML est l’analyseur derrière une quantité énorme d’outils : Ansible, d’anciens clients Kubernetes, d’innombrables scripts. yaml.v3 de Go et le js-yaml actuel suivent 1.2. Le même document peut donc être lu de deux manières selon qui l’ouvre, et la seule sortie sûre partout est celle quotée pour 1.1.
C’est le réglage par défaut ici. Passer à 1.2 ne cache rien : la sortie est réémise avec les résolveurs récents et le panneau des constats se réduit, si bien que vous voyez précisément quels guillemets étaient là pour l’ancien schéma. Ceux qui restent sont ceux dont tout analyseur a besoin.
Les chaînes qui cassent la syntaxe, pas le type
Un second groupe de chaînes doit être quoté pour une autre raison : non parce que YAML les lirait comme un autre type, mais parce qu’elles ne s’analyseraient pas du tout comme du texte.
- Deux-points suivis d’une espace terminent une clé. « note: time: now » se lirait comme une clé note dont la valeur est une clé time.
- Une espace suivie d’un croisillon ouvre un commentaire : tout ce qui suit disparaît.
- Un -, ?, :, [, ], {, }, #, &, *, !, |, >, %, @ ou accent grave en tête est un caractère indicateur et a un sens structurel.
- Une espace initiale ou finale n’est pas conservée par une valeur non quotée : « x » revient sans elles.
- Une tabulation où que ce soit dans la valeur est rejetée d’emblée — PyYAML refuse le document entier plutôt que de le mal lire, si bien que celle-là échoue bruyamment.
Les apostrophes sont employées partout où elles suffisent, car elles n’ont qu’une seule règle d’échappement — une apostrophe s’écrit deux fois — et se lisent mieux que les échappements à contre-oblique qu’imposent les guillemets doubles. Ces derniers sont réservés à ce qui doit vraiment être échappé : caractères de contrôle, tabulations, et chaînes multilignes qui ne peuvent pas passer par un bloc.
Chaînes multilignes et indicateur de coupe
Une chaîne contenant des sauts de ligne — un script, un certificat, un bloc de prose — est en général la raison même pour laquelle on veut du YAML. JSON ne peut l’écrire qu’avec des échappements contre-oblique-n sur une seule très longue ligne ; YAML dispose du scalaire de bloc littéral, introduit par une barre verticale, où le texte apparaît indenté et lisible en dessous.
La subtilité tient à ce qu’il advient des sauts de ligne finaux, ce que règle l’indicateur de coupe :
- Une barre verticale seule rogne : quel que soit le nombre de sauts finaux du bloc, la valeur en garde exactement un.
- Une barre verticale suivie d’un moins supprime : la valeur n’en garde aucun.
- Une barre verticale suivie d’un plus conserve : la valeur les garde tous.
Cet outil choisit l’indicateur d’après la chaîne qu’il a reçue, de sorte que la valeur survit exactement à l’aller-retour. Cela vaut d’être su, car la valeur par défaut — la barre seule — est celle qu’on écrit à la main, et elle normalise en silence une chaîne qui se terminait par deux sauts de ligne ou par aucun.
Un scalaire de bloc ne peut pas tout porter, et là où il ne peut pas, la sortie retombe sur des guillemets doubles et le panneau des constats dit pourquoi. Un retour chariot ne survit pas, car les scalaires de bloc normalisent les sauts de ligne. Une première ligne commençant par une espace serait lue comme de l’indentation supplémentaire et retirée. Et une ligne finissant par une espace est conservée par la spécification, mais elle est invisible à l’écran et la plupart des éditeurs la suppriment à l’enregistrement : la quoter est donc plus sûr — c’est une décision et non une limitation, et elle est signalée comme telle.
Plus d’un document
YAML a quelque chose que JSON n’a pas : un fichier peut contenir un flux de documents séparés par trois tirets. C’est le format d’un manifeste Kubernetes, et c’est pourquoi un tableau JSON doit si souvent devenir autre chose qu’une séquence YAML.
Le commutateur ici émet chaque élément d’un tableau de premier niveau comme document distinct. Et quand l’entrée n’est pas une seule valeur JSON mais que chaque ligne s’analyse seule, elle est lue comme du NDJSON — le format à une ligne par enregistrement dans lequel arrivent journaux et exports d’API — et chaque ligne devient un document. Cette lecture est une supposition : elle est donc signalée au-dessus de la sortie plutôt que faite en silence.
Ce repli ne s’applique que si l’entrée entière échoue à s’analyser et que chaque ligne y parvient, ce qu’un document simplement mal formé ne fera pas. Une erreur de syntaxe reste une erreur de syntaxe, avec la ligne et la colonne où elle s’est produite.
Ce que la conversion ne peut pas préserver
Deux choses sont perdues avant même que cet outil ne voie vos données, toutes deux dans l’analyse JSON elle-même, et il vaut mieux savoir lesquelles.
Les clés dupliquées. JSON permet à un objet de lister deux fois la même clé et la plupart des analyseurs gardent la dernière en silence. YAML interdit purement et simplement les doublons : la sortie sera donc valide, mais la valeur antérieure a déjà disparu — et aucun convertisseur ne peut signaler ce qu’il n’a jamais reçu.
La précision des entiers. Un nombre JSON supérieur à environ neuf millions de milliards ne survit pas à l’analyse en double : un identifiant comme 12345678901234567890 revient arrondi. Ce n’est ni un problème de YAML ni un problème introduit par cet outil ; cela arrive dans tous les analyseurs JSON du langage. Si un grand identifiant compte, il a sa place dans une chaîne des deux côtés.
Remarques sur la sortie
L’indentation se fait en espaces, toujours, car YAML interdit complètement les tabulations pour indenter : c’est l’une des rares choses sur lesquelles le format est strict. Deux espaces est la convention ; quatre sont proposés parce que certains styles maison les veulent.
Les séquences sont indentées sous leur clé. Cette forme et la forme non indentée sont l’une comme l’autre du YAML valide et signifient la même chose ; l’indentée est celle que la plupart des gens écrivent et que la plupart des éditeurs replient correctement.
Un tableau ou un objet vide s’écrit en style de flot, par une paire de crochets ou d’accolades, car le style de bloc n’a aucun moyen d’exprimer le vide : il n’y a rien à écrire sur les lignes suivantes.
La sortie se termine par un saut de ligne, et c’est fonctionnel et non décoratif. La coupe d’un scalaire de bloc se mesure au saut de ligne qui le suit : un bloc rogné tout à la fin d’un fichier sans saut final perd le saut qu’il devait garder.
Questions fréquentes
- Le JSON est-il déjà du YAML valide ?
- Sous YAML 1.2, oui : la spécification le dit explicitement, et un analyseur 1.2 lira un fichier JSON directement. Cela ne sert pas à grand-chose en pratique, car la raison de convertir est la lisibilité — commentaires, scalaires de bloc, pas d’accolades — et coller du JSON dans un fichier YAML ne vous en donne rien. Sous YAML 1.1 ce n’est pas tout à fait vrai, une raison de plus de distinguer les deux versions.
- Pourquoi ma chaîne a-t-elle reçu des guillemets dont elle semble ne pas avoir besoin ?
- Elle en a presque certainement besoin. YAML type une valeur non quotée par correspondance de motifs : NO, yes, off, 12:30, 0755, 1.10, 2024-01-30 et la chaîne vide cessent tous d’être des chaînes. Le panneau des constats nomme chacun et montre la valeur qu’il serait devenu, pour que l’affirmation se vérifie au lieu de se croire. Si vous visez un analyseur YAML 1.2, changer de schéma retire ceux dont seul 1.1 a besoin.
- Quelle est ici la différence entre YAML 1.1 et 1.2 ?
- 1.2 a laissé tomber les résolveurs à l’origine de la plupart des surprises : yes/no/on/off ne sont plus des booléens, la base 60 a disparu et il n’y a pas de type horodatage. PyYAML implémente 1.1 et reste partout : la sortie prudente est donc le défaut, et le réglage 1.2 existe pour quand vous savez ce qui lira le fichier.
- Peut-il reconvertir du YAML en JSON ?
- Non, délibérément. Un lecteur YAML a besoin d’ancres, d’alias, de balises, de clés de fusion, de cinq styles de scalaires et de deux versions de schéma ; se tromper subtilement sur l’un d’eux revient à accepter un fichier et à rendre des données différentes de celles qu’il contenait. Cet échec est silencieux, ce qui le rend pire que l’absence de la fonction.
- Comment obtenir un fichier multidocument à la Kubernetes ?
- Activez le commutateur qui émet chaque élément d’un tableau de premier niveau comme document distinct : le tableau devient des documents séparés par trois tirets. Si votre entrée est du NDJSON — un objet JSON par ligne, comme arrivent souvent journaux et exports d’API — c’est détecté automatiquement et signalé au-dessus de la sortie.
- Pourquoi n’y a-t-il pas de commentaires dans la sortie ?
- Parce qu’il n’y en avait pas dans l’entrée. Les commentaires sont l’apport principal de YAML par rapport à JSON, et un convertisseur ne peut pas les inventer. À retenir aussi dans l’autre sens : si vous faites passer un fichier YAML par JSON et retour, tous ses commentaires ont disparu.
- Ce que je colle est-il envoyé à un serveur ?
- Non. L’analyse et la conversion s’exécutent entièrement dans votre navigateur ; rien n’est téléversé ni journalisé, et cela fonctionne sans connexion réseau.