JSON-zu-YAML-Konverter

Wandelt JSON in YAML um und erklärt jedes gesetzte Anführungszeichen — die Zeichenketten, die ohne es still zu Wahrheitswerten, Zahlen oder Daten würden.

Eingabe
YAML
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
Warum jede Zeichenkette Anführungszeichen hat

Zitierte Werte: 6. Nur von YAML 1.1 verlangt: 4. Wechseln Sie oben das Schema, um den Unterschied zu sehen.

  • countrynur 1.1

    „NO“ würde als der Wahrheitswert false gelesen.

  • startsAtnur 1.1

    „12:30“ würde zur Basis 60 als 750 gelesen.

  • mode

    „0755“ hat eine führende Null und würde als die Zahl 493 gelesen.

  • version

    „1.10“ würde als die Zahl 1.1 gelesen.

  • releasednur 1.1

    „2024-01-30“ würde als Datum gelesen und nicht als Text.

  • enablednur 1.1

    „yes“ würde als der Wahrheitswert true gelesen.

Was dieses Werkzeug tut

Es wandelt ein JSON-Dokument in YAML um und sagt Ihnen anschließend, warum jede Zeichenkette in Anführungszeichen steht. Dieser zweite Teil ist der Grund, warum es das Werkzeug gibt: Jeder andere Konverter gibt die Ausgabe zurück und überlässt es Ihnen, später zu entdecken, dass einer Ihrer Werte keine Zeichenkette mehr ist.

Die Umwandlung läuft in eine Richtung. YAML zu lesen ist ein weit größeres Problem, als es zu schreiben, und ein halb richtiger YAML-Parser ist schlimmer als gar keiner — er nimmt Ihre Datei an und gibt klaglos die falschen Daten zurück. Das Ausgeben ist begrenzt, und diese Richtung wird hier abgedeckt.

Warum ein Konverter überhaupt Meinungen braucht

JSON sagt, welchen Typ alles hat. Eine Zeichenkette hat Anführungszeichen, eine Zahl nicht, und eine dritte Möglichkeit gibt es nicht. YAML dagegen entscheidet den Typ eines nicht zitierten Werts anhand seiner Form: Passt er auf das Muster eines Wahrheitswerts, ist er einer; passt er auf eine Zahl, ist er eine Zahl; und nur wenn er auf nichts passt, bleibt er Text.

Genau das macht YAML angenehm von Hand zu schreiben und die Umwandlung dorthin zu einer Ermessensfrage. Jede Zeichenkette der Eingabe muss gegen jedes Muster geprüft werden, das YAML auflöst, und zitiert werden, wenn sie eines trifft. Irren Sie sich zur sicheren Seite, wird die Ausgabe laut; irren Sie sich zur anderen, ändert ein Wert still seinen Typ.

Das Norwegen-Problem und seine Verwandtschaft

Der bekannteste Fall ist eine Liste von Ländercodes. Norwegen ist NO, und in YAML 1.1 ist das nicht zitierte Token NO der Wahrheitswert false. Eine Konfigurationsdatei, die Länder aufzählt, verliert Norwegen und gewinnt ein false, und nirgendwo meldet irgendetwas einen Fehler.

Es ist keine einzelne kuriose Regel, sondern eine ganze Familie. YAML 1.1 liest y, Y, yes, no, on und off als Wahrheitswerte, in jeder Schreibweise, und erwischt damit ein chemisches Symbol, eine Schalterstellung und die Antwort auf eine Frage. Und die Zahlen-Resolver sind noch seltsamer:

  • 12:30 ist 750. YAML 1.1 liest durch Doppelpunkte getrennte Ziffern zur Basis 60, also wird aus einer Tageszeit oder einer Dauer eine ganze Zahl.
  • 0755 ist 493. Eine führende Null bedeutet in YAML 1.1 oktal — und in YAML 1.2 ist derselbe Text die Dezimalzahl 755: Die beiden Versionen streiten darüber, welche Zahl, nicht darüber, ob.
  • 1.10 ist 1.1. Eine zweiteilige Versionsnummer ist eine Fließkommazahl, und die abschließende Null verschwindet. Eine auf 1.10 festgenagelte Abhängigkeit zeigt nun auf 1.1.
  • 2024-01-30 ist ein Datumsobjekt und keine Zeichenkette, denn YAML 1.1 hat einen Zeitstempel-Typ.
  • Eine leere Zeichenkette ist null, ebenso die nackten Wörter null, Null, NULL und die Tilde.

Nichts davon ist ein Fehler in YAML. Es sind die Resolver, die genau das tun, was sie versprechen, an Text, der zufällig passt. Die einzige Abwehr ist, alles Passende zu zitieren — was dieses Werkzeug tut und was die Befundliste Zeile für Zeile ausweist.

Zwei Versionen, und warum die ältere die Voreinstellung ist

YAML 1.2 kam 2009 und entfernte die meisten überraschenden Resolver. Sein Kernschema behält nur true und false als Wahrheitswerte, lässt die Basis 60 ganz fallen und hat keinen Zeitstempel-Typ. Unter 1.2 sind NO und 12:30 und 2024-01-30 einfach Zeichenketten.

Der Haken ist, was Ihre Datei tatsächlich liest. PyYAML setzt YAML 1.1 um, und PyYAML steckt hinter einer enormen Menge an Werkzeugen — Ansible, ältere Kubernetes-Clients, unzählige Skripte. Gos yaml.v3 und das heutige js-yaml folgen 1.2. Dasselbe Dokument kann also auf zwei Weisen gelesen werden, je nachdem, wer es öffnet, und die einzige überall sichere Ausgabe ist die für 1.1 zitierte.

Das ist hier die Voreinstellung. Der Wechsel auf 1.2 verbirgt nichts — es wird mit den neueren Resolvern neu ausgegeben und die Befundliste schrumpft, sodass Sie genau sehen, welche Anführungszeichen dem älteren Schema galten. Die verbleibenden sind die, die jeder Parser braucht.

Zeichenketten, die die Syntax brechen statt den Typ

Eine zweite Gruppe muss aus einem anderen Grund zitiert werden: nicht weil YAML sie als anderen Typ läse, sondern weil sie überhaupt nicht als Text zu lesen wären.

  • Ein Doppelpunkt gefolgt von einem Leerzeichen beendet einen Schlüssel. „note: time: now“ würde als Schlüssel note gelesen, dessen Wert ein Schlüssel time ist.
  • Ein Leerzeichen gefolgt von einer Raute beginnt einen Kommentar, alles danach verschwindet also.
  • Ein führendes -, ?, :, [, ], {, }, #, &, *, !, |, >, %, @ oder Gravis ist ein Indikatorzeichen und bedeutet etwas Strukturelles.
  • Führende oder abschließende Leerzeichen bewahrt ein nicht zitierter Wert nicht, „ x “ kommt also als „x“ zurück.
  • Ein Tabulator irgendwo im Wert wird rundweg abgelehnt — PyYAML verweigert das ganze Dokument, statt es falsch zu lesen; dieser Fall scheitert also laut.

Einfache Anführungszeichen werden überall dort verwendet, wo sie genügen, denn sie haben genau eine Escape-Regel — ein Apostroph wird verdoppelt — und lesen sich besser als die Backslash-Escapes der doppelten. Doppelte bleiben dem vorbehalten, was wirklich Escapes braucht: Steuerzeichen, Tabulatoren und mehrzeilige Zeichenketten, die keinen Block verwenden können.

Mehrzeilige Zeichenketten und der Chomping-Indikator

Eine Zeichenkette mit Zeilenumbrüchen — ein Skript, ein Zertifikat, ein Absatz Prosa — ist meist überhaupt erst der Grund, YAML zu wollen. JSON kann sie nur mit Backslash-n-Escapes in einer sehr langen Zeile schreiben; YAML hat den literalen Blockskalar, eingeleitet durch einen senkrechten Strich, unter dem der Text eingerückt und lesbar steht.

Die Feinheit betrifft die Zeilenumbrüche am Ende, gesteuert vom Chomping-Indikator:

  • Ein bloßer senkrechter Strich beschneidet: Wie viele abschließende Umbrüche der Block auch hat, der Wert bekommt genau einen.
  • Ein senkrechter Strich mit Minus entfernt: Der Wert bekommt keinen.
  • Ein senkrechter Strich mit Plus behält: Der Wert bekommt jeden einzelnen.

Dieses Werkzeug wählt den Indikator nach der Zeichenkette, die es bekommen hat, sodass der Wert den Hin- und Rückweg exakt übersteht. Das ist wissenswert, weil die Voreinstellung — der bloße Strich — die ist, die man von Hand schreibt, und sie normalisiert still eine Zeichenkette, die auf zwei Umbrüche oder auf keinen endete.

Ein Blockskalar kann nicht alles tragen, und wo er es nicht kann, fällt die Ausgabe auf doppelte Anführungszeichen zurück und die Befundliste sagt, warum. Ein Wagenrücklauf übersteht es nicht, weil Blockskalare Zeilenumbrüche normalisieren. Eine erste Zeile, die mit einem Leerzeichen beginnt, würde als zusätzliche Einrückung gelesen und entfernt. Und eine Zeile, die auf ein Leerzeichen endet, bewahrt die Spezifikation zwar, doch sie ist am Bildschirm unsichtbar und wird von den meisten Editoren beim Speichern entfernt — Zitieren ist daher sicherer. Das ist eine Entscheidung, keine Beschränkung, und wird als solche gemeldet.

Mehr als ein Dokument

YAML hat etwas, das JSON nicht hat: Eine Datei kann einen Strom von Dokumenten enthalten, getrennt durch drei Bindestriche. Das ist das Format eines Kubernetes-Manifests, und deshalb muss ein JSON-Array so oft etwas anderes werden als eine YAML-Sequenz.

Der Schalter hier gibt jedes Element eines Arrays auf oberster Ebene als eigenes Dokument aus. Und wenn die Eingabe gar kein einzelner JSON-Wert ist, sich aber jede Zeile für sich lesen lässt, wird sie als NDJSON gelesen — das zeilenweise Format, in dem Protokolle und API-Exporte kommen — und jede Zeile wird ein Dokument. Diese Lesart ist eine Vermutung und wird deshalb über der Ausgabe gemeldet statt still getroffen.

Der Rückfall greift nur, wenn die gesamte Eingabe scheitert und jede Zeile gelingt, was ein bloß fehlerhaftes Dokument nicht tut. Ein Syntaxfehler erscheint weiterhin als Syntaxfehler, mit Zeile und Spalte seines Auftretens.

Was die Umwandlung nicht erhalten kann

Zwei Dinge gehen verloren, bevor dieses Werkzeug Ihre Daten überhaupt sieht, beide im JSON-Parsen selbst, und es lohnt sich zu wissen, welche.

Doppelte Schlüssel. JSON erlaubt einem Objekt, denselben Schlüssel zweimal zu führen, und die meisten Parser behalten still den letzten. YAML verbietet Duplikate rundweg; die Ausgabe wird also gültig sein, doch der frühere Wert ist bereits fort — und kein Konverter kann melden, was er nie erhalten hat.

Ganzzahlgenauigkeit. Eine JSON-Zahl über etwa neun Billiarden übersteht das Parsen in ein Double nicht, eine Kennung wie 12345678901234567890 kommt also gerundet zurück. Das ist kein YAML-Problem und keines, das dieses Werkzeug einführt; es passiert in jedem JSON-Parser der Sprache. Wenn eine große Kennung zählt, gehört sie auf beiden Seiten in eine Zeichenkette.

Anmerkungen zur Ausgabe

Eingerückt wird mit Leerzeichen, immer, denn YAML verbietet Tabulatoren zum Einrücken vollständig — eines der wenigen Dinge, bei denen das Format streng ist. Zwei Leerzeichen sind die Konvention; vier werden angeboten, weil manche Hausstile sie wollen.

Sequenzen werden unter ihrem Schlüssel eingerückt. Sowohl das als auch die nicht eingerückte Form sind gültiges YAML und bedeuten dasselbe; die eingerückte schreiben die meisten Menschen, und die meisten Editoren falten sie richtig.

Ein leeres Array oder Objekt wird im Flussstil als Klammerpaar geschrieben, weil der Blockstil keine Möglichkeit hat, Leere auszudrücken: Auf den folgenden Zeilen wäre nichts zu schreiben.

Die Ausgabe endet mit einem Zeilenumbruch, und das trägt, statt bloß ordentlich zu sein. Das Chomping eines Blockskalars misst sich an dem Umbruch, der ihm folgt; ein beschnittener Block ganz am Dateiende ohne abschließenden Umbruch verliert also den Umbruch, den er behalten sollte.

Kubernetes-Manifeste und die Felder, die Zeichenketten bleiben müssen

Kubernetes liest ein Manifest in beiden Formaten. Die eigene Dokumentation nennt YAML die Konvention und JSON die Alternative, und kubectl wandelt ein Manifest in JSON um, oder in eine andere Serialisierung, die die API unterstützt, wenn es die Anfrage stellt — es geht beim Umwandeln also nicht darum, was der Cluster annimmt. Es geht um die Datei, die bei Ihnen bleibt: YAML ist das, was ein Reviewer liest, worin ein Diff im Pull Request lesbar ist, und das Einzige der beiden, das einen Kommentar tragen kann. Das JSON kommt meist aus kubectl get -o json, aus einer Vorlage oder aus einer API, die Objekte zurückgibt.

  • Eine Datei, mehrere Objekte. Manifeste dürfen in einer Datei zusammengefasst werden, getrennt durch drei Bindestriche, und die Dokumentation sagt ausdrücklich, dass sie in der Reihenfolge angelegt werden, in der sie dort stehen — weshalb ein Service üblicherweise über dem Deployment steht, das ihn füllt. Der Schalter, der jedes Element eines Arrays auf oberster Ebene als eigenes Dokument ausgibt, macht aus einer JSON-Liste von Objekten genau so eine Datei.
  • Die Umgebungseinträge eines Containers sind zwei Zeichenkettenfelder. Die API-Referenz erklärt name wie value zur Zeichenkette, ein JSON-Wert von "true" muss also mit seinen Anführungszeichen herauskommen: ohne sie ist er ein Wahrheitswert, und ein Wahrheitswert ist nicht der Typ, den das Feld halten soll.
  • Ein Container-Port ist als ganze Zahl erklärt und steht wenige Zeilen von jenen Zeichenketten. Die beiden brauchen die entgegengesetzte Behandlung, und das JSON trägt den Unterschied schon: eine Zahl wird zur schlichten Zahl, und eine Zeichenkette wird nur dort zitiert, wo YAML aufhören würde, sie als eine zu lesen.
  • Labels und Annotationen sind Abbildungen von Zeichenkette auf Zeichenkette. Dort landet das Norwegen-Problem mitten im Manifest: ein Label mit dem Wert NO, on oder off ist für einen YAML-1.1-Parser ein Wahrheitswert, und der Wert 1.10 ist eine Fließkommazahl, die ihre abschließende Null verliert.

Drei Umgebungseinträge, als JSON gegeben und mit lauter Zeichenketten als Werten, werden hierzu:

env:
  - name: DEBUG
    value: 'true'
  - name: REPLICAS
    value: '3'
  - name: COUNTRY
    value: 'NO'

Alle drei sind zitiert, und die Befundliste nennt alle drei mitsamt dem Wert, der jeweils daraus geworden wäre: true ist ein Wahrheitswert, 3 eine Zahl, und NO ist das false. Nur der letzte davon hängt an der Version — stellen Sie das Schema auf 1.2, und seine Anführungszeichen fallen weg, denn 1.2 liest NO als nichts anderes als Text. Die anderen zwei behalten ihre unter beiden.

Docker Compose, wo die Referenz des Formats selbst vor YAML warnt

Eine Compose-Datei ist YAML, und die Referenz von Docker dazu trägt zwei Warnungen über das Parsen von YAML. Dass die Dokumentation eines Produkts das eigene Serialisierungsformat als Gefahr benennt, ist ungewöhnlich, und beide Warnungen betreffen genau das, wofür dieses Werkzeug da ist: einen Wert, der Text sein soll und den ein Parser als etwas anderes liest.

  • Ports. Die Referenz sagt, eine Zuordnung HOST:CONTAINER solle immer als zitierte Zeichenkette geschrieben werden, um einen Konflikt mit der Fließkommazahl zur Basis 60 in YAML zu vermeiden. Ohne Anführungszeichen ist 22:22 die ganze Zahl 1342.
  • Umgebungswerte. Die Referenz bittet darum, true, false, yes und no in Anführungszeichen zu setzen, damit der Parser sie nicht umwandelt. Zwei der vier sind Wahrheitswerte unter beiden YAML-Versionen und zwei — yes und no — allein unter 1.1, weshalb die Befundliste sie unterschiedlich kennzeichnet.
  • Die Regel zur Basis 60 reicht nur an eine Zuordnung, deren Zahl nach dem Doppelpunkt unter sechzig liegt, denn so weit reicht eine Stelle zur Basis 60. Deshalb ist 22:22 hier zitiert und 8080:80 bleibt schlicht, und der Unterschied ist die Regel und kein Urteil darüber, welche Ports wichtig sind.

Ein Dienst, dessen Ports und Umgebungswerte im JSON alle Zeichenketten sind, wird hierzu:

services:
  proxy:
    image: nginx
    ports:
      - '22:22'
      - 8080:80
    environment:
      TLS_ENABLED: 'no'
      DEBUG: 'true'

Das ist die Ausgabe, um die die Referenz bittet, und das voreingestellte Schema ist das, was sie erzeugt. Es ist auch der klarste Grund, das Schema zu lassen: Stellen Sie auf 1.2, und die Port-Zuordnung und das no verlieren ihre Anführungszeichen, während das true die seinen behält, denn 1.2 hat die Basis 60 aufgegeben und behält als Wahrheitswerte nur true und false. Ein Parser, der 1.2 umsetzt, liest das Ergebnis weiterhin richtig — aber der Rat von Docker ist ohne jede solche Bedingung geschrieben, und ihm zu folgen kostet zwei Paar Anführungszeichen.

Häufig gestellte Fragen

Ist JSON bereits gültiges YAML?
Unter YAML 1.2 ja: Die Spezifikation sagt es ausdrücklich, und ein 1.2-Parser liest eine JSON-Datei direkt. Praktisch nützt das wenig, denn der Grund umzuwandeln ist Lesbarkeit — Kommentare, Blockskalare, keine geschweiften Klammern — und JSON in eine YAML-Datei zu kleben bringt davon nichts. Unter YAML 1.1 stimmt es nicht ganz, ein weiterer Grund, die beiden Versionen auseinanderzuhalten.
Warum hat meine Zeichenkette Anführungszeichen bekommen, die sie nicht zu brauchen scheint?
Sie braucht sie fast sicher doch. YAML typisiert einen nicht zitierten Wert über Muster, also hören NO, yes, off, 12:30, 0755, 1.10, 2024-01-30 und die leere Zeichenkette allesamt auf, Zeichenketten zu sein. Die Befundliste nennt jeden Fall und zeigt den Wert, der daraus geworden wäre — nachprüfbar statt zu glauben. Zielen Sie auf einen YAML-1.2-Parser, entfernt der Schemawechsel die, die nur 1.1 braucht.
Was ist hier der Unterschied zwischen YAML 1.1 und 1.2?
1.2 hat die Resolver fallen gelassen, die die meisten Überraschungen verursachen: yes/no/on/off sind keine Wahrheitswerte mehr, die Basis 60 ist weg, und einen Zeitstempel-Typ gibt es nicht. PyYAML setzt 1.1 um und ist noch überall, deshalb ist die konservative Ausgabe voreingestellt; die 1.2-Einstellung ist da, wenn Sie wissen, was die Datei liest.
Kann es YAML zurück in JSON wandeln?
Nein, mit Absicht. Ein YAML-Leser braucht Anker, Aliase, Tags, Merge-Schlüssel, fünf Skalarstile und zwei Schemaversionen, und sich bei einem davon fein zu irren heißt, eine Datei anzunehmen und andere Daten zurückzugeben, als sie enthielt. Dieses Versagen ist stumm, was es schlimmer macht, als die Funktion gar nicht anzubieten.
Wie bekomme ich eine Mehrdokumentdatei im Kubernetes-Stil?
Schalten Sie den Schalter ein, der jedes Element eines Arrays auf oberster Ebene als eigenes Dokument ausgibt — das Array wird zu Dokumenten, getrennt durch drei Bindestriche. Ist Ihre Eingabe stattdessen NDJSON — ein JSON-Objekt je Zeile, wie Protokolle und API-Exporte oft kommen —, wird das automatisch erkannt und über der Ausgabe gemeldet.
Warum stehen keine Kommentare in der Ausgabe?
Weil in der Eingabe keine standen. Kommentare sind das Wichtigste, was YAML hat und JSON nicht, und ein Konverter kann sie nicht erfinden. Das gilt auch andersherum: Schicken Sie eine YAML-Datei durch JSON und zurück, ist jeder Kommentar darin fort.
Wird etwas von dem, was ich einfüge, an einen Server gesendet?
Nein. Parsen und Umwandeln laufen vollständig in Ihrem Browser; nichts wird hochgeladen oder protokolliert, und es funktioniert ohne Netzverbindung.
Wie wandle ich die JSON-Ausgabe von kubectl in ein YAML-Manifest um?
Einfügen und das YAML lesen. Kubernetes nimmt beide Formate — seine Dokumentation nennt YAML die Konvention und JSON die Alternative —, der Grund umzuwandeln liegt also in der Datei, die bei Ihnen bleibt, und nicht darin, was der Cluster annimmt. Zu prüfen sind die Anführungszeichen: ein Manifest ist voll von Feldern, die die API zur Zeichenkette erklärt, darunter Umgebungswerte und die Werte von Labels und Annotationen, und genau bei denen würde YAML den Typ wechseln. Ist das JSON eine Liste mehrerer Objekte, macht der Schalter für mehrere Dokumente eine einzige Datei daraus.
Warum will Docker Compose meine Ports in Anführungszeichen?
Weil 22:22 für einen YAML-1.1-Parser kein Zahlenpaar ist, sondern eine Zahl zur Basis 60 — 1342. Die Compose-Referenz von Docker sagt aus genau diesem Grund, eine Zuordnung HOST:CONTAINER solle immer eine zitierte Zeichenkette sein, und dieselbe Seite bittet darum, true, false, yes und no in einem Umgebungsblock ebenfalls zu zitieren. Beides tut dieses Werkzeug unter seinem voreingestellten Schema, und die Befundliste sagt, aus welcher Regel jedes Anführungszeichen kommt. Eine Zuordnung, deren Zahl nach dem Doppelpunkt sechzig oder größer ist, etwa 8080:80, liegt außerhalb der Regel zur Basis 60 und bleibt schlicht.
Welche YAML-Version soll ich für Kubernetes oder Docker Compose wählen?
Die voreingestellte, 1.1. Jedes Anführungszeichen, das sie setzt, nimmt auch ein 1.2-Parser an, die konservative Ausgabe ist also in beiden Fällen sicher, und beide Warnungen in der Compose-Referenz betreffen Regeln von 1.1 — Port-Zuordnungen zur Basis 60, und yes und no als Wahrheitswerte. Die Einstellung 1.2 ist dafür da, zu zeigen, welche Anführungszeichen nur wegen des älteren Schemas da sind; die Ausgabe verliert sie, und das ist das Gegenteil dessen, worum jene Warnungen bitten.

Verwandte Werkzeuge