STXT Transform
1. Introducción
Este documento es STXT-TRANSFORM-SPEC; las demás especificaciones lo citan con ese nombre.
Este documento define STXT Transform: las operaciones que llevan el contenido de un documento STXT a otro formato de datos, lo traen desde él y lo completan con datos externos. Son tres:
| Operación | Entrada | Salida |
|---|---|---|
| Exportación (export) | Un documento STXT | El mismo contenido en otro formato: JSON, YAML, XML |
| Importación (import) | Un documento en otro formato | El mismo contenido como documento STXT |
| Relleno (fill) | Un documento STXT con Slots y unos datos | Un documento STXT completo |
Un Slot es el lugar de un documento que espera un dato. El relleno pone en cada Slot el dato que le corresponde.
Su propósito es que un documento STXT pueda ser la fuente de los programas que ya leen JSON, YAML o XML, y que los datos que ya existen en esos formatos puedan pasar a STXT, sin escribir una conversión propia para cada namespace.
La exportación y la importación se apoyan en la definición del namespace del documento, sea un schema o un template. El texto de un documento no dice qué valor es un número, qué nodo es una lista ni cómo se llaman sus elementos: lo dice su definición. Por eso estas dos operaciones apenas necesitan más información que el documento y su definición, y por eso mismo esta especificación exige para ellas, de momento, que el documento tenga namespace y que ese namespace tenga definición.
El relleno no necesita definición ni namespace: lo que hace cada Slot está escrito en el propio documento.
Esta especificación no cambia la sintaxis de STXT-SPEC ni la validación de STXT-SCHEMA-SPEC: es una capa posterior al parseo y a la validación, y opcional como ellas.
1.1 Fecha y estado de esta especificación
Esta especificación lleva su propia fecha y su propio estado en los campos Last modif y
Status de su Metadata, independientes de los de las demás especificaciones de STXT y
con el significado que fija STXT-SPEC §1.1. Está en Genesis: en
construcción, y cualquier parte de ella puede cambiar sin aviso.
Depende de STXT-SPEC y de STXT-SCHEMA-SPEC.
Hoy contiene la presentación de las tres operaciones y dos ejemplos: la exportación y la importación con JSON, y un primer esbozo del relleno de Slots. Las reglas de cada formato y las de los Slots están por escribir.
1.2 Relación con el árbol canónico
STXT-TREE-SPEC ya define una representación JSON de un documento: el árbol canónico. Su propósito es otro. El árbol canónico describe el resultado del parseo, con cada nodo como un objeto que lleva su nombre, su nombre canónico, su namespace, su forma y su valor, y existe para comparar implementaciones. No necesita definición, y todos los valores son texto.
La exportación de esta especificación produce el JSON que escribiría quien diseñara ese dato directamente en JSON: objetos con una clave por nodo, arrays, números y booleanos. Necesita la definición, y es la forma pensada para que la consuma un programa.
1.3 Relación con los templates
Un documento con Slots no es un @stxt.template. Un template
(STXT-TEMPLATE-SPEC) describe la estructura de todos los
documentos de un namespace y sirve para validarlos. Un documento con Slots es
un documento, con namespace o sin él, al que le faltan valores: sus Slots se rellenan con
unos datos externos, por ejemplo un JSON, y el resultado es un documento completo, que
se valida como cualquier otro.
Para evitar la confusión, esta especificación no llama «plantilla» ni «template» al documento con Slots.
2. Terminología
Las palabras clave "DEBE", "NO DEBE", "DEBERÍA", "NO DEBERÍA", y "PUEDE" deben interpretarse según RFC 2119 y RFC 8174: tienen ese significado únicamente cuando aparecen en mayúsculas, como aquí.
Términos como nodo, namespace, schema, template, tipo y cardinalidad mantienen su significado en STXT-SPEC, STXT-SCHEMA-SPEC y STXT-TEMPLATE-SPEC.
Definiciones adicionales:
- Definición: el schema o el template del namespace de un documento, como en STXT-DISCOVERY-SPEC.
- Formato externo: un formato de datos distinto de STXT, como JSON, YAML o XML.
- Exportación: la operación que produce, a partir de un documento STXT y su definición, un documento en un formato externo.
- Importación: la operación que produce, a partir de un documento en un formato externo y una definición, un documento STXT.
- Slot: el lugar de un documento STXT que el relleno sustituye por un dato.
- Documento con Slots: un documento STXT que contiene uno o más Slots.
- Relleno: la operación que produce un documento STXT completo a partir de un documento con Slots y unos datos.
3. Un ejemplo: STXT y JSON
Esta sección no es normativa. Muestra la dirección de la exportación y la importación con el formato más sencillo.
Un documento:
# El servidor web de la oficina
Servidor (com.example.servidores):
Nombre: web-01
Activo: true
Puertos:
Puerto: 80
Puerto: 443
Responsable:
Persona: Ana Ruiz
Correo: ana@example.com
Notas >>
Reiniciar tras cada despliegue.
No apagar en horario de oficina.Y la definición de su namespace, aquí un template:
Template (@stxt.template): com.example.servidores
Structure >>
Servidor (com.example.servidores): GROUP
Nombre: (1)
Activo: (1) BOOLEAN
Puertos: (1) GROUP
Puerto: (+) NATURAL
Responsable: (?) GROUP
Persona: (1)
Correo: (1) EMAIL
Notas: (?) TEXT3.1 Exportación
La exportación del documento a JSON:
{
"Nombre": "web-01",
"Activo": true,
"Puertos": [80, 443],
"Responsable": {
"Persona": "Ana Ruiz",
"Correo": "ana@example.com"
},
"Notas": "Reiniciar tras cada despliegue.\nNo apagar en horario de oficina."
}
Lo que decide la definición:
| En el documento | En la definición | En JSON |
|---|---|---|
Nombre: web-01 |
Sin tipo | Un string |
Activo: true |
BOOLEAN |
Un booleano |
Puerto: 80 |
NATURAL |
Un número |
Puertos, con dos Puerto |
GROUP con un solo hijo, que se repite |
Un array. El nombre Puerto no aparece |
Responsable, con dos hijos |
GROUP con hijos distintos |
Un objeto, con una clave por hijo |
Notas >> |
TEXT |
Un string, con las líneas separadas por \n |
- Sin definición,
80ytrueserían texto, y nada distinguiría una lista de un nodo con un solo hijo. - El comentario no se exporta: no forma parte del árbol del documento.
- El nodo raíz no aparece: el JSON es el contenido de
Servidor.
Como contraste, el nodo Puertos en el árbol canónico de
STXT-TREE-SPEC, que en la exportación es [80, 443]:
{
"name": "Puertos",
"canonicalName": "puertos",
"namespace": "com.example.servidores",
"form": "inline",
"value": "",
"children": [
{
"name": "Puerto",
"canonicalName": "puerto",
"namespace": "com.example.servidores",
"form": "inline",
"value": "80",
"children": []
},
{
"name": "Puerto",
"canonicalName": "puerto",
"namespace": "com.example.servidores",
"form": "inline",
"value": "443",
"children": []
}
]
}
3.2 Importación
La importación es el camino inverso. Recibe el JSON anterior y el nodo raíz que debe
producir, Servidor (com.example.servidores), y devuelve este documento:
Servidor (com.example.servidores):
Nombre: web-01
Activo: true
Puertos:
Puerto: 80
Puerto: 443
Responsable:
Persona: Ana Ruiz
Correo: ana@example.com
Notas >>
Reiniciar tras cada despliegue.
No apagar en horario de oficina.La definición aporta lo que el JSON no lleva:
- El nombre
Puertode cada elemento del arrayPuertos. - El namespace de cada nodo.
- La forma de cada nodo:
Notasse escribe como bloque>>porque su texto tiene más de una línea yTEXTadmite las dos formas.
El documento importado tiene el mismo árbol que el original. Solo se ha perdido el comentario.
4. Un ejemplo: relleno de Slots
Esta sección no es normativa. Es un primer esbozo de los Slots y de cómo se combinan.
Un documento con Slots:
Pedido (com.example.pedidos): $numero$
Fecha: $fecha$
Moneda: EUR
Cliente: {cliente}
Nombre: $nombre$
Correo: $correo$
# El teléfono es opcional
Teléfono: ?$telefono$
Línea: [lineas]$producto$
Cantidad: $cantidad$
Precio: $precio$
Nota: ?$nota$
Envío: [envios]
Transportista: $transportista$
Bulto: [bultos]Los datos, en JSON:
{
"numero": "2026-0142",
"fecha": "2026-10-12",
"cliente": {
"nombre": "Librería Atenea",
"correo": "pedidos@atenea.example"
},
"lineas": [
{ "producto": "Cuaderno A5", "cantidad": 40, "precio": 3.25, "nota": "Tapa azul" },
{ "producto": "Lápiz HB", "cantidad": 200, "precio": 0.45 }
],
"envios": [
{ "transportista": "Correos", "bultos": ["C-01", "C-02"] },
{ "transportista": "MRW", "bultos": ["M-07"] }
]
}
Y el documento que produce el relleno:
Pedido (com.example.pedidos): 2026-0142
Fecha: 2026-10-12
Moneda: EUR
Cliente:
Nombre: Librería Atenea
Correo: pedidos@atenea.example
Línea: Cuaderno A5
Cantidad: 40
Precio: 3.25
Nota: Tapa azul
Línea: Lápiz HB
Cantidad: 200
Precio: 0.45
Envío:
Transportista: Correos
Bulto: C-01
Bulto: C-02
Envío:
Transportista: MRW
Bulto: M-07Los Slots del ejemplo:
| Slot | Qué hace | En el ejemplo |
|---|---|---|
$var$ |
Pone el valor del dato var |
Fecha: $fecha$ |
{objeto} |
Entra en el objeto objeto: los Slots del nodo y de sus hijos se buscan dentro de él |
Cliente: {cliente} |
[lista] |
Repite el nodo, con sus hijos, una vez por cada elemento del array lista |
Línea, Envío, Bulto |
? delante |
Hace opcional el Slot: si el dato no existe, el nodo no aparece | Teléfono: ?$telefono$ |
- Si el elemento de un array es un objeto, el relleno entra en él: cada
Envíobusca sutransportistay susbultosen su propio elemento. - Si el elemento es un valor, es el valor del nodo:
Bulto: [bultos]produceBulto: C-01yBulto: C-02. - Un nodo puede combinar Slots:
Línea: [lineas]$producto$repite el nodo y pone en cada uno suproducto. Primero se evalúa[lista], después{objeto}y por último$var$. - Un valor sin Slots se copia tal cual:
Moneda: EUR. - Todo Slot es obligatorio, sea
$var$,{objeto}o[lista], salvo que lleve?delante: si faltaracantidaden una línea, oclienteen los datos, el relleno fallaría. Teléfonono aparece porque el cliente no tienetelefono.Notaaparece en la primeraLíneay no en la segunda.- Un array vacío no produce ningún nodo y no es un error del relleno. Si el nodo era obligatorio, lo dirá la validación del documento rellenado.
- Un dato que no encaja con su Slot es un error: un objeto donde
$var$espera un valor, o un valor donde[lista]espera un array. - El comentario no pasa al documento rellenado.
- Un documento con Slots no se valida. El que se valida es siempre el documento rellenado.