Ir para o conteúdo
jsonbeautifiers
Português

YAML para JSON

Streams multidocumento e uma chave para a armadilha dos booleanos do YAML 1.1.

YAML
JSON

Nada do que você cola sai do seu navegador. A lista de permissões connect-src transforma isso em uma garantia do navegador, e não em uma promessa. Confira você mesmo

Converta YAML para JSON, com suporte a múltiplos documentos e uma chave para as regras de tipagem que mais causam confusão.

É nesta direção que as coisas dão errado, e quase tudo se resume a qual versão de YAML as suas outras ferramentas implementam.

O problema da Noruega, demonstrado

No YAML 1.1 as palavras soltas no, yes, on, off, y e n são booleanos. Então uma lista de países contendo NO para a Noruega é lida como false. No YAML 1.2 são strings comuns.

Isso importa porque a divisão atravessa o ecossistema inteiro. PyYAML, o Psych do Ruby e várias ferramentas antigas implementam 1.1. js-yaml, o yaml.v3 do Go e a maioria dos parsers modernos implementam 1.2. O mesmo arquivo significa coisas diferentes dependendo de quem lê.

Aqui você pode trocar as regras de tipagem e ver um valor mudar na sua frente. Medido com js-yaml 5.4.1: `a: no` dá a string "no" no YAML 1.2 e o booleano false no YAML 1.1. Mesmo no modo 1.2, esta ferramenta avisa quando vê um no ou um yes sem aspas, porque a próxima ferramenta do seu pipeline pode não concordar com ela.

As outras coisas que o YAML tem e o JSON não

Comentários
Perdidos, para sempre. O JSON não tem sintaxe de comentário. Se você mantém o YAML à mão, esta é uma conversão de mão única.
Âncoras e aliases
São expandidos no lugar. Um documento que usa uma âncora cinco vezes vira cinco cópias no JSON, que pode ficar bem maior.
Timestamps
O YAML resolve escalares com cara de data para datas de verdade. O JSON não tem tipo data, então elas são escritas como strings ISO 8601. Escolha as regras de tipagem JSON para que fiquem como strings simples desde o começo.
Chaves que não são strings
O YAML permite um número ou até uma sequência como chave de mapping. O JSON não, então elas viram strings.
.inf e .nan
Sem equivalente em JSON, então viram null.
Vários documentos
Um stream separado por --- contém vários documentos. Por padrão o primeiro é convertido e você é avisado de que havia mais; ligue "todos os documentos" para receber um array.

Tabulações

O YAML proíbe tabulações para indentação, de forma absoluta e sem exceções. É o erro de YAML mais comum que existe, e acontece porque algum editor está configurado para inserir tabulações. Esta ferramenta avisa sobre tabulações antes mesmo de tentar fazer o parsing, já que a mensagem resultante de qualquer parser não ajuda em nada.

How to do this in code

Convertendo em código, e o argumento de segurança que vem junto.

py Python

O PyYAML implementa YAML 1.1, então é aqui que "no" vira 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

O js-yaml implementa YAML 1.2, então aqui "no" continua sendo string.

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

Perguntas frequentes

Por que o meu valor virou true ou false?
Você está lendo com um parser de YAML 1.1, onde no, yes, on, off, y e n são booleanos. Ponha o valor entre aspas, ou use um parser de YAML 1.2. Troque as regras de tipagem acima para ver a diferença no seu próprio documento.
Para onde foram os meus comentários?
O JSON não tem comentários, então eles são descartados. Não há como contornar. Se o YAML é um arquivo que você mantém, guarde-o como fonte da verdade e gere o JSON a partir dele.
Por que yaml.load é inseguro em Python?
Porque ele pode instanciar objetos Python arbitrários a partir de tags no documento, o que torna fazer parsing de YAML não confiável equivalente a executá-lo. Use sempre safe_load.