STXT frente a YAML
YAML y STXT usan la indentación para definir la jerarquía. El modelo mental es distinto: YAML tiene mapas y listas, como JSON, y STXT tiene árboles de nodos de texto, como XML.
El mismo contenido, dos veces
Un descriptor de servicio en YAML:
service: billing
replicas: 2
ports:
- 8080
- 8443
maintainer: ana@example.com
notes: |
Restarted after the 2026-08-31 incident.
The TLS certificate expires on 2027-03-01.
Y en STXT:
Service: billing
Replicas: 2
Ports:
Port: 8080
Port: 8443
Maintainer: ana@example.com
Notes >>
Restarted after the 2026-08-31 incident.
The TLS certificate expires on 2027-03-01.Un documento sencillo se parece en los dos. Las diferencias son estas:
| YAML | STXT | |
|---|---|---|
| Valores | El tipo lo decide la grafía: 2 es un entero y "2" una cadena |
Todo valor es texto. El tipo, si hace falta, lo declara la plantilla |
| Listas | Dos sintaxis: de bloque (- 8080) y de flujo ([8080, 8443]) |
No hay sintaxis de lista: un hijo repetido es la lista (FAQ) |
| Indentación | Cualquier número de espacios por nivel, y sin tabuladores | Un tabulador o cuatro espacios por nivel |
| Texto de varias líneas | Escalares de bloque, con varios indicadores | Un nodo block >> |
| Namespaces | No tiene | Forman parte del lenguaje (STXT-SPEC §7) |
| Esquemas | Herramientas externas | Forman parte del lenguaje, y son opcionales |
Cuando la grafía cambia el significado
En YAML, un valor sin comillas se convierte a un tipo según su forma. Las reglas cambiaron entre las versiones 1.1 y 1.2 del lenguaje:
country: NO # false en YAML 1.1; la cadena "NO" en 1.2
version: 3.10 # el número 3.1 en las dos
window: 12:30 # el entero 750 en YAML 1.1 (sexagesimal); una cadena en 1.2
enabled: yes # true en 1.1; la cadena "yes" en 1.2
Para conservar NO, 3.10 o 12:30 como texto hay que ponerlos entre comillas.
En STXT un valor es siempre los caracteres escritos:
| Nombre nodo | Valor del nodo |
|---|---|
| Country | NO |
| Version | 3.10 |
| Window | 12:30 |
| Enabled | yes |
Si Enabled debe ser un booleano, lo dice la plantilla (Enabled: (1) BOOLEAN).
En ese caso el validador rechaza yes, y no lo convierte.
El texto de varias líneas
Un escalar de bloque de YAML combina varios indicadores: el estilo (| literal o > plegado),
el salto de línea final (-, + o ninguno) y, si hace falta, la indentación:
literal: |
first line
second line
folded: >
first line
second line
kept: |+
first line
next: value
Cada combinación produce una cadena distinta:
| Clave | Valor |
|---|---|
literal |
"first line\nsecond line\n" |
folded |
"first line second line\n" |
kept |
"first line\n\n" (conserva la línea vacía que le sigue) |
STXT tiene una sola forma, el nodo block. El texto es literal, sin variantes y sin caracteres de escape:
Se conservan la indentación adicional y las líneas vacías intermedias. Se descartan los blancos al final de cada línea y las líneas vacías finales (STXT-SPEC §10).
Seguridad
YAML incluye dos características que STXT no tiene:
- Anclas y alias (
&a,*a): un documento pequeño puede expandirse a una estructura enorme en memoria. - Etiquetas de tipo (
!!python/object,!ruby/object): las específicas de una implementación han permitido instanciar objetos arbitrarios al cargar un documento. De ahí las funcionessafe_loadde las bibliotecas.
STXT no tiene referencias, anclas, etiquetas, inclusión ni entidades. El parseo es lineal, línea a línea y en una sola pasada (STXT-SPEC §15).
La validación
YAML se valida con herramientas externas, normalmente JSON Schema sobre la estructura ya cargada. En STXT los esquemas forman parte del lenguaje. El descriptor del principio, con namespace:
Service (com.example.deploy): billing
Replicas: 2
Port: 8080
Port: 8443
Maintainer: ana@example.com
Notes >>
The TLS certificate expires on 2027-03-01.Y la plantilla de su namespace:
Template (@stxt.template): com.example.deploy
Structure >>
Service (com.example.deploy):
Replicas: (1) NATURAL
Port: (+) NATURAL
Maintainer: (1) EMAIL
Notes: (?) TEXTAquí no hace falta el contenedor Ports: la cardinalidad (+) ya dice que Port se repite.
Un documento con errores no valida:
# ERROR: este documento no valida
Service (com.example.deploy): billing
# `two` no es un NATURAL
Replicas: two
# Falta al menos un `Port`
# `ana` no es un EMAIL
Maintainer: ana
# `Region` no está en la plantilla
Region: eu-west-1¿Y TOML?
TOML comparte objetivo con STXT: ficheros que una persona escribe y lee. La jerarquía no está en la indentación, sino en cabeceras que repiten la ruta completa de su tabla:
[[job]]
name = "database"
[[job.step]]
run = "pg_dump acme > acme.sql"
[[job.step]]
run = "gzip acme.sql"
[[job]]
name = "documents"
[[job.step]]
run = "tar cf documents.tar /srv/docs"
Cada [[job.step]] pertenece al último [[job]] abierto. En STXT cada nivel se escribe una vez,
y un hijo pertenece al nodo bajo el que está indentado:
Backup:
Job: database
Step: pg_dump acme > acme.sql
Step: gzip acme.sql
Job: documents
Step: tar cf documents.tar /srv/docsComo en YAML, el tipo de un valor lo decide su grafía: 14 es un entero y "14" una cadena.
Las cadenas van siempre entre comillas, y las de varias líneas no se pueden sangrar con su tabla.
No tiene namespaces ni esquemas.
¿Y NestedText?
NestedText toma varias de las decisiones de STXT: todo valor es texto, sin tipos implícitos ni caracteres de escape, y la estructura está en la indentación. El descriptor del principio:
service: billing
replicas: 2
ports:
- 8080
- 8443
maintainer: ana@example.com
notes:
> Restarted after the 2026-08-31 incident.
> The TLS certificate expires on 2027-03-01.
Y en STXT:
Service: billing
Replicas: 2
Ports:
Port: 8080
Port: 8443
Maintainer: ana@example.com
Notes >>
Restarted after the 2026-08-31 incident.
The TLS certificate expires on 2027-03-01.2 y 8080 son cadenas en los dos, y el texto de varias líneas es literal: en NestedText
cada línea empieza por >, y en STXT va bajo un nodo block.
NestedText conserva el modelo de datos de YAML (diccionarios, listas y cadenas), y deja los tipos y la validación a la aplicación. No tiene namespaces ni esquemas.