Zum Hauptinhalt springen

YAML in JSON umwandeln

Dieses Tool konvertiert ein YAML-Dokument nach JSON, direkt in Ihrem Browser und nach dem Core-Schema von YAML 1.2. Das ist wichtiger, als es klingt: Nach dem älteren Vorgänger von 1.2, den PyYAML und Ruby noch verwenden, werden die Tokens NO, yes, on und off ohne Anführungszeichen als boolesche Werte aufgefasst – eine Liste von ISO-Ländercodes verliert dadurch Norwegen. Hier bleiben sie Strings, und alles, was sich nach 1.1 anders auflösen würde, wird markiert.

Nur lokal
Einrückung
YAML
0 B1 ZeileZ. 1, Sp. 1
JSONschreibgeschützt
0 B1 Zeile

Wie funktioniert YAML in JSON umwandeln?

YAML sieht einfach aus und ist es nicht. Die Spezifikation ist länger als die von JSON, XML und TOML zusammen, und die meisten Überraschungen gehen auf eine einzige Designentscheidung zurück: Skalare ohne Anführungszeichen werden anhand eines Musters aufgelöst, statt per Syntax deklariert zu sein. Was ein Token bedeutet, hängt davon ab, welche Auflösungstabelle der jeweilige Leser verwendet.

Das Norwegen-Problem ist ein Versionsproblem

YAML 1.1 löste y, yes, on, n, no und off als boolesche Werte auf. countries: [NO, SE, DK] lud also als [false, "SE", "DK"], und ein norway: no in einer Konfigurationsdatei bedeutete etwas, das niemand beabsichtigt hatte. YAML 1.2 hat alle diese Werte gestrichen – zusammen mit den sexagesimalen Zahlen, weshalb 1.1 12:30 als die ganze Zahl 750 las.

Der Haken: Die Software, die Menschen tatsächlich einsetzen, ist gespalten. Der Standard-Loader von PyYAML und Psych von Ruby sind 1.1; yaml.v3 von Go und moderne JavaScript-Parser sind 1.2. Dieser Konverter wendet 1.2 an und nennt Ihnen namentlich jeden Token, bei dem ein 1.1-Leser abweichen würde – denn die nützliche Ausgabe ist nicht nur das JSON, sondern auch das Wissen, dass die Datei mehrdeutig ist.

Anker werden expandiert – mit einem Budget

&name definiert einen Anker, *name verweist auf ihn. JSON hat kein Äquivalent, daher wird jede Referenz zu einer Kopie expandiert. Genau diese Expansion ist der „billion laughs“-Angriff: Zehn Anker, von denen jeder den vorherigen zweifach referenziert, expandieren zu 1.024 Knoten, zwanzig zu einer Million, dreißig zu mehr als einer Milliarde. Eine 200-Byte-Datei kann den Heap erschöpfen. Die Expansion wird bei 100.000 Knoten begrenzt, und diese Grenze wird gemeldet – das ist der Unterschied zwischen einer klaren Fehlermeldung und einem eingefrorenen Tab.

Block-Skalare behalten ihre Zeilenumbrüche

| behält Zeilenumbrüche, > faltet sie zu Leerzeichen zusammen, und der Chomping-Indikator entscheidet, was mit dem letzten passiert: | behält genau einen, |- entfernt alle, |+ behält jeden. Dieser letzte Unterschied ist wichtig bei einem PEM-Schlüssel oder einem Shell-Skript, dessen letzte Zeile zwingend abgeschlossen sein muss. Ein # innerhalb eines Block-Skalars ist Inhalt, kein Kommentar – ein Parser, der ihn entfernt, frisst jedem Skript den Shebang weg.

Doppelte Schlüssel werden gemeldet, nicht versteckt

Die YAML-Spezifikation sagt, dass ein doppelter Schlüssel ein Fehler ist. Die meisten Parser behalten stillschweigend den letzten. Dieser behält ebenfalls den letzten, genau wie JSON.parse, und sagt Ihnen, welcher Schlüssel betroffen ist und in welcher Zeile – denn ein Duplikat in einer Konfigurationsdatei ist fast immer ein schiefgegangener Merge.

YAML

regions: [NO, SE]
version: "007"
retry: 012

JSON

{
  "regions": ["NO", "SE"],
  "version": "007",
  "retry": 12
}
// warning: 012 — leading zero, 1.1 reads it as octal

Welche Optionen und Sonderfälle unterstützt YAML in JSON umwandeln?

Technische Referenz und Optionen
ParameterTypStandardVerhalten & Sonderfälle
true / falseBooleschaufgelöstNur diese beiden Schreibweisen, in beliebiger Groß-/Kleinschreibung. Das ist der ganze Unterschied zu YAML 1.1 – und der Grund, warum Norwegen überlebt.
yes / no / on / off / y / nstringmarkiertUnter 1.2 Zeichenfolgen, unter 1.1 Booleans. Jedes wird namentlich gemeldet, damit Sie wissen, dass die Datei in verschiedenen Runtimes Unterschiedliches bedeutet.
~ / null / (leer)nullaufgelöstAlle drei bedeuten JSON-null. Ein leerer Wert nach einem Schlüssel ist null, keine leere Zeichenfolge.
012Ganzzahl12, markiert1.2 liest die führende Null als Dezimalzahl; 1.1 als Oktal 10; gemeint war wahrscheinlich die Zeichenfolge. In Anführungszeichen setzen, um die Null zu behalten.
0o17 / 0x1fGanzzahl15 / 31Explizites Oktal und Hexadezimal. 1.2 verlangt das 0o-Präfix für Oktal – deshalb ist ein nacktes 017 nicht 15.
.inf / .nanstringals Text behaltenJSON kennt keins von beiden; eine Ausgabe würde ein Dokument erzeugen, das JSON.parse ablehnt. Das Token bleibt wörtlich stehen und wird markiert.
Anker und AliasseexpandiertLimit von 100,000 KnotenJeder *alias wird zu einer Kopie, denn JSON hat keine Referenzen. Das Limit verhindert, dass eine Billion-laughs-Expansion den Speicher erschöpft.
Merge-Keys (<<)nicht unterstütztgemeldetAbgelehnt statt halb implementiert. Die Merge-Semantik interagiert mit Überschreiben und Reihenfolge auf eine Weise, die leicht subtil falsch gerät und schwer zu bemerken ist.
Multi-Dokumentdurch --- getrenntArrayMehrere Dokumente werden ein JSON-Array. Schalten Sie die Option aus, um nur das erste zu konvertieren – was ein Kubernetes-Manifest-Bundle meist will.
EingabegrößeBytes8 MBDas Parsen läuft im Hauptthread. Über der Obergrenze lehnt das Tool ab, statt den Tab einzufrieren.

Häufig gestellte Fragen

Warum ist mein `no` ein String statt false?

Weil dieser Parser dem Core-Schema von YAML 1.2 folgt, in dem nur true und false boolesche Werte sind. YAML 1.1 – der Standard-Loader von PyYAML und Psych von Ruby nutzen es bis heute – löst no, yes, on, off, y und n als boolesche Werte auf, und genau dadurch verliert eine Liste von ISO-Ländercodes stillschweigend Norwegen. Wenn Sie einen booleschen Wert wollen, schreiben Sie true oder false; wenn Sie den String wollen, haben Sie ihn bereits.

Welche YAML-Version kann ich bei meinen Tools voraussetzen?

Prüfen Sie, statt anzunehmen – die Spaltung ist real, und in der Praxis wird die Version nirgends ausgewiesen: safe_load von PyYAML und Psych von Ruby sind 1.1, gopkg.in/yaml.v3 von Go und die meisten aktuellen JavaScript-Parser sind 1.2. Die verlässliche Antwort: Setzen Sie alles Mehrdeutige in Anführungszeichen. Ein in Anführungszeichen gesetzter Skalar ist in jeder jemals veröffentlichten YAML-Version ein String – damit hat sich die Frage erledigt.

Was ist mit meinen Ankern passiert?

Sie wurden expandiert. JSON kann eine Referenz nicht ausdrücken, daher wird jeder *alias zu einer vollständigen Kopie des Ankerinhalts. Das ist für die Daten verlustfrei und für die Struktur verlustbehaftet: Die Information, dass zwei Teile des Dokuments dasselbe Objekt waren, ist weg. Wenn Sie das erhalten müssen, ist JSON das falsche Ziel.

Warum hat das Tool die Expansion meiner Aliase verweigert?

Verschachtelte Aliase multiplizieren sich. Wenn jeder Anker den vorherigen zweifach referenziert, expandieren dreißig Ebenen zu mehr als einer Milliarde Knoten – aus einer Datei, die auf einen einzigen Bildschirm passt. Das ist der „billion laughs“-Angriff, der bereits echte Dienste lahmgelegt hat. Die Expansion stoppt bei 100.000 Knoten und meldet das, statt weiterzuwachsen, bis der Tab stirbt.

Warum behält meine Zahl in der Ausgabe ihre Anführungszeichen?

Weil Sie sie im YAML in Anführungszeichen gesetzt haben – und ein in Anführungszeichen gesetzter Skalar ist in jeder YAML-Version ein String. Das ist korrektes Verhalten und meistens auch die Absicht: version: "007" und version: 007 sind wirklich unterschiedliche Werte, und nur einer von beiden übersteht einen Roundtrip exakt so, wie er geschrieben wurde.

Wird mein YAML hochgeladen?

Nein. Parsen und Umwandlung laufen beide in dem Tab, den Sie bereits offen haben – beobachten Sie das Netzwerk-Panel, während Sie einfügen. Gerade bei YAML ist das wichtig: Das YAML, das Menschen umwandeln müssen, ist meist ein Kubernetes-Manifest, eine CI-Workflow-Datei oder eine docker-compose-Datei – also eine Datei voller Infrastrukturdetails und manchmal auch Secrets.