Pular para o conteúdo principal

Converter YAML em JSON

O YAML para JSON converte um documento YAML para JSON no seu navegador usando o esquema core do YAML 1.2. Isso importa mais do que parece: sob o antecessor do 1.2 ainda usado por PyYAML e Ruby, os tokens sem aspas NO, yes, on e off se resolvem como booleanos, então uma lista de códigos ISO de países perde a Noruega. Aqui eles continuam strings, e qualquer coisa que se resolveria de forma diferente sob o 1.1 é sinalizada.

Só local
Recuo
YAML
0 B1 linhaLin. 1, Col. 1
JSONsomente leitura
0 B1 linha

Como funciona o Converter YAML em JSON?

YAML parece simples e não é. A especificação é mais longa do que as de JSON, XML e TOML somadas, e a maior parte das surpresas vem de uma decisão de design: escalares sem aspas são resolvidos por padrão de texto, e não declarados por sintaxe. O que um token significa depende de qual tabela de resolução o leitor está usando.

O problema da Noruega é um problema de versionamento

O YAML 1.1 resolvia y, yes, on, n, no e off como booleanos. Então countries: [NO, SE, DK] carregava como [false, "SE", "DK"], e um arquivo de configuração que dizia norway: no significava algo que ninguém pretendia. O YAML 1.2 removeu todos eles, junto com os números sexagesimais — razão pela qual o 1.1 lia 12:30 como o inteiro 750.

O detalhe é que o software que as pessoas realmente rodam está dividido. O loader padrão do PyYAML e o Psych do Ruby são 1.1; o yaml.v3 do Go e os parsers JavaScript modernos são 1.2. Este conversor aplica o 1.2 e diz a você, pelo nome, cada token em que um leitor 1.1 discordaria — porque a saída útil não é só o JSON, mas o saber de que o arquivo é ambíguo.

Âncoras são expandidas, com um orçamento

&name define uma âncora e *name a referencia. O JSON não tem equivalente, então cada referência é expandida em uma cópia. Essa expansão é o ataque "billion laughs": dez âncoras, cada uma referenciando a anterior duas vezes, expandem para 1,024 nós, vinte para um milhão, trinta para mais de um bilhão. Um arquivo de 200 bytes pode esgotar o heap. A expansão tem um teto de 100,000 nós, e o teto é relatado — que é a diferença entre um erro claro e uma aba travada.

Escalares de bloco mantêm suas quebras de linha

| mantém as quebras de linha, > as dobra em espaços, e o indicador de chomping decide o que acontece com a última: | mantém exatamente uma, |- remove todas, |+ mantém cada uma. Essa última distinção importa para uma chave PEM ou um shell script cuja linha final precisa ser terminada. Um # dentro de um escalar de bloco é conteúdo, não comentário — um parser que o remove come o shebang de todo script.

Chaves duplicadas são relatadas, não escondidas

O YAML diz que chave duplicada é um erro. A maioria dos parsers guarda a última em silêncio. Este guarda a última, igual ao JSON.parse, e diz qual chave e em qual linha — porque uma duplicata em um arquivo de configuração quase sempre é um merge que deu errado.

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

Quais opções e casos-limite o Converter YAML em JSON suporta?

Referência técnica e opções
ParâmetroTipoPadrãoComportamento e casos-limite
true / falsebooleanoresolvidosSomente essas duas grafias, em qualquer combinação de maiúsculas. Essa é toda a diferença em relação ao YAML 1.1 — e a razão de a Noruega sobreviver.
yes / no / on / off / y / nstringsinalizadosStrings no 1.2, booleanos no 1.1. Cada um é sinalizado pelo nome, para você saber que o arquivo significa coisas diferentes em runtimes diferentes.
~ / null / (vazio)nullresolvidosOs três representam um null de JSON. Um valor vazio depois de uma chave é null, não uma string vazia.
012inteiro12, sinalizadoO 1.2 lê o zero à esquerda como decimal; o 1.1, como octal 10; o autor provavelmente queria a string. Coloque entre aspas para manter o zero.
0o17 / 0x1finteiro15 / 31Octal e hexadecimal explícitos. O 1.2 exige o prefixo 0o para octal, e é por isso que um 017 puro não é 15.
.inf / .nanstringmantidos como textoO JSON não tem nenhum dos dois, então emitir um deles gera um documento que o JSON.parse rejeita. O token fica como está e é sinalizado.
Âncoras e aliasesexpandidoslimite de 100,000 nósCada *alias vira uma cópia, já que o JSON não tem referências. O limite impede que uma expansão billion-laughs esgote a memória.
Chaves de mesclagem (<<)não suportadonotificadoRejeitado em vez de implementado pela metade. A semântica de mesclagem interage com sobreposição e ordenação de formas fáceis de errar sutilmente e difíceis de perceber.
Multi-documentoseparados por ---arrayVários documentos viram um array JSON. Desligue a opção para converter apenas o primeiro, que é o que um pacote de manifests do Kubernetes geralmente quer.
Tamanho da entradabytes8 MBA análise roda na thread principal. Acima do teto, a ferramenta recusa em vez de travar a aba.

Perguntas frequentes

Por que meu `no` é uma string em vez de false?

Porque este parser aplica o esquema core do YAML 1.2, em que só true e false são booleanos. O YAML 1.1 — ainda o que o loader padrão do PyYAML e o Psych do Ruby usam — resolve no, yes, on, off, y e n como booleanos, e é assim que uma lista de códigos ISO de países perde a Noruega em silêncio. Se você quer um booleano, escreva true ou false; se quer a string, você já a tem.

Qual versão do YAML devo assumir que as minhas ferramentas usam?

Verifique em vez de assumir, porque a divisão é real e, na prática, não vem identificada: o safe_load do PyYAML e o Psych do Ruby são 1.1, o gopkg.in/yaml.v3 do Go e a maioria dos parsers JavaScript atuais são 1.2. A resposta confiável é colocar entre aspas tudo o que for ambíguo — um escalar entre aspas é uma string em toda versão de YAML já publicada, o que torna a pergunta irrelevante.

O que aconteceu com as minhas âncoras?

Elas foram expandidas. O JSON não tem como expressar uma referência, então cada *alias se torna uma cópia completa do que a âncora guardava. Isso é sem perdas para os dados e com perdas para a estrutura: o fato de duas partes do documento serem o mesmo objeto se perde. Se você precisa disso preservado, JSON é o alvo errado.

Por que ele se recusou a expandir os meus aliases?

Aliases aninhados se multiplicam. Se cada âncora referencia a anterior duas vezes, trinta níveis expandem para mais de um bilhão de nós a partir de um arquivo que cabe em uma tela — o ataque billion-laughs, que já derrubou serviços de verdade. A expansão para em 100,000 nós e avisa, em vez de crescer até a aba morrer.

Por que meu número mantém as aspas na saída?

Porque você o colocou entre aspas no YAML, e um escalar entre aspas é uma string em toda versão do YAML. Esse é o comportamento correto e geralmente a intenção: version: "007" e version: 007 são valores genuinamente diferentes, e só um deles sobrevive a uma ida e volta exatamente como foi escrito.

Meu YAML é enviado?

Não. O parse e a conversão rodam ambos na aba que você já tem aberta — observe o painel Network enquanto cola. Isso importa especificamente para YAML, porque o YAML que as pessoas precisam converter costuma ser um manifest do Kubernetes, um workflow de CI ou um arquivo docker-compose, ou seja, um arquivo cheio de detalhes de infraestrutura e, às vezes, segredos.