Saltar al contenido
jsonbeautifiers
Español

YAML a JSON

Streams multidocumento y un interruptor para la trampa de los booleanos de YAML 1.1.

YAML
JSON

Nada de lo que pegues sale de tu navegador. La lista de permitidos de connect-src convierte eso en una garantía del navegador, no en una promesa. Compruébalo tú mismo

Convierte YAML a JSON, con soporte multidocumento y un interruptor para las reglas de tipado que más confusión causan.

Esta dirección es donde las cosas se tuercen, y casi todo se reduce a qué versión de YAML implementan tus otras herramientas.

El problema de Noruega, demostrado

En YAML 1.1 las palabras sueltas no, yes, on, off, y y n son booleanos. Así que una lista de países que contiene NO para Noruega se parsea como false. En YAML 1.2 son cadenas corrientes.

Esto importa porque la división atraviesa todo el ecosistema. PyYAML, Psych de Ruby y varias herramientas antiguas implementan 1.1. js-yaml, yaml.v3 de Go y la mayoría de parsers modernos implementan 1.2. El mismo archivo significa cosas distintas según quién lo lea.

Aquí puedes cambiar las reglas de tipado y ver cómo un valor cambia delante de ti. Medido con js-yaml 5.4.1: `a: no` da la cadena "no" con YAML 1.2 y el booleano false con YAML 1.1. Incluso en modo 1.2, esta herramienta avisa cuando ve un no o un yes sin comillas, porque puede que la siguiente herramienta de tu pipeline no esté de acuerdo con ella.

Las demás cosas que YAML tiene y JSON no

Comentarios
Se pierden, para siempre. JSON no tiene sintaxis de comentarios. Si mantienes el YAML a mano, esta es una conversión de un solo sentido.
Anclas y alias
Se expanden en línea. Un documento que usa un ancla cinco veces pasa a tener cinco copias en el JSON, que puede resultar bastante más grande.
Marcas de tiempo
YAML resuelve los escalares con forma de fecha a fechas reales. JSON no tiene tipo fecha, así que se escriben como cadenas ISO 8601. Elige las reglas de tipado JSON para que se queden como cadenas simples desde el principio.
Claves que no son cadenas
YAML permite un número o incluso una secuencia como clave de un mapping. JSON no, así que se convierten en cadenas.
.inf y .nan
No tienen equivalente en JSON, así que pasan a ser null.
Varios documentos
Un stream separado por --- contiene varios documentos. Por defecto se convierte el primero y se te avisa de que había más; activa «todos los documentos» para obtener un array.

Tabuladores

YAML prohíbe los tabuladores para la indentación, de forma absoluta y sin excepciones. Es el error de YAML más habitual que existe, y ocurre porque un editor está configurado para insertar tabuladores. Esta herramienta avisa de los tabuladores antes siquiera de intentar parsear, ya que el mensaje resultante de cualquier parser no ayuda nada.

How to do this in code

Convertir en código, y el argumento de seguridad que lo acompaña.

py Python

PyYAML implementa YAML 1.1, así que aquí es donde "no" se convierte en 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

js-yaml implementa YAML 1.2, así que aquí "no" sigue siendo una cadena.

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

Preguntas frecuentes

¿Por qué mi valor se ha convertido en true o false?
Lo estás leyendo con un parser de YAML 1.1, donde no, yes, on, off, y y n son booleanos. Entrecomilla el valor, o usa un parser de YAML 1.2. Cambia las reglas de tipado de arriba para ver la diferencia sobre tu propio documento.
¿Dónde han ido a parar mis comentarios?
JSON no tiene comentarios, así que se descartan. No hay forma de evitarlo. Si el YAML es un archivo que mantienes tú, consérvalo como fuente de verdad y genera el JSON a partir de él.
¿Por qué yaml.load es inseguro en Python?
Porque puede instanciar objetos Python arbitrarios a partir de etiquetas del documento, lo que hace que parsear YAML no confiable equivalga a ejecutarlo. Usa siempre safe_load.