STXT Transform

Status:
Genesis
last modified:
2026-10-12

1. Introduction

This document is STXT-TRANSFORM-SPEC; the other specifications cite it by that name.

This document defines STXT Transform: the operations that take the content of an STXT document to another data format, bring it back from one and complete it with external data. There are three:

Operation Input Output
Export An STXT document The same content in another format: JSON, YAML, XML
Import A document in another format The same content as an STXT document
Fill An STXT document with Slots, and data A complete STXT document

A Slot is the place of a document that waits for a piece of data. Fill puts in every Slot the data that belongs to it.

Its purpose is that an STXT document can be the source of the programs that already read JSON, YAML or XML, and that the data already existing in those formats can move to STXT, without writing a conversion of its own for every namespace.

Export and import rely on the definition of the namespace of the document, whether a schema or a template. The text of a document does not say which value is a number, which node is a list or how its elements are named: its definition does. That is why these two operations need little more information than the document and its definition, and why this specification requires for them, for now, that the document has a namespace and that the namespace has a definition.

Fill needs neither a definition nor a namespace: what every Slot does is written in the document itself.

This specification changes neither the syntax of STXT-SPEC nor the validation of STXT-SCHEMA-SPEC: it is a layer that comes after parsing and validation, and optional like them.

1.1 Date and status of this specification

This specification carries its own date and its own status in the Last modif and Status fields of its Metadata, independent of the other STXT specifications' and with the meaning fixed by STXT-SPEC §1.1. It is in Genesis: under construction, and any part of it may change without notice. It depends on STXT-SPEC and STXT-SCHEMA-SPEC.

Today it holds the presentation of the three operations and two examples: export and import with JSON, and a first sketch of the fill of Slots. The rules of each format and those of Slots are still to be written.

1.2 Relation to the canonical tree

STXT-TREE-SPEC already defines a JSON representation of a document: the canonical tree. Its purpose is a different one. The canonical tree describes the result of parsing, with every node as an object that carries its name, its canonical name, its namespace, its form and its value, and it exists to compare implementations. It needs no definition, and every value is text.

The export of this specification produces the JSON that someone designing that data directly in JSON would write: objects with one key per node, arrays, numbers and booleans. It needs the definition, and it is the form meant to be consumed by a program.

1.3 Relation to templates

A document with Slots is not a @stxt.template. A template (STXT-TEMPLATE-SPEC) describes the structure of every document of a namespace and is used to validate them. A document with Slots is one document, with or without a namespace, with values missing: its Slots are filled with external data, for example a JSON text, and the result is a complete document, which is validated like any other.

To avoid the confusion, this specification never calls the document with Slots a "template".

2. Terminology

The keywords "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" must be interpreted according to RFC 2119 and RFC 8174: they carry that meaning only when they appear in uppercase, as here.

Terms such as node, namespace, schema, template, type and cardinality retain their meaning in STXT-SPEC, STXT-SCHEMA-SPEC and STXT-TEMPLATE-SPEC.

Additional definitions:

  • Definition: the schema or the template of the namespace of a document, as in STXT-DISCOVERY-SPEC.
  • External format: a data format other than STXT, such as JSON, YAML or XML.
  • Export: the operation that produces, from an STXT document and its definition, a document in an external format.
  • Import: the operation that produces, from a document in an external format and a definition, an STXT document.
  • Slot: the place of an STXT document that fill replaces with a piece of data.
  • Document with Slots: an STXT document that contains one or more Slots.
  • Fill: the operation that produces a complete STXT document from a document with Slots and some data.

3. An example: STXT and JSON

This section is not normative. It shows the direction of export and import with the simplest format.

A document:

# The web server of the office
Server (com.example.servers):
	Name: web-01
	Active: true
	Ports:
		Port: 80
		Port: 443
	Owner:
		Person: Ana Ruiz
		Email: ana@example.com
	Notes >>
		Restart after every deployment.
		Do not switch off during office hours.

And the definition of its namespace, here a template:

Template (@stxt.template): com.example.servers
	Structure >>
		Server (com.example.servers): GROUP
			Name: (1)
			Active: (1) BOOLEAN
			Ports: (1) GROUP
				Port: (+) NATURAL
			Owner: (?) GROUP
				Person: (1)
				Email: (1) EMAIL
			Notes: (?) TEXT

3.1 Export

The export of the document to JSON:

{
	"Name": "web-01",
	"Active": true,
	"Ports": [80, 443],
	"Owner": {
		"Person": "Ana Ruiz",
		"Email": "ana@example.com"
	},
	"Notes": "Restart after every deployment.\nDo not switch off during office hours."
}

What the definition decides:

In the document In the definition In JSON
Name: web-01 No type A string
Active: true BOOLEAN A boolean
Port: 80 NATURAL A number
Ports, with two Port GROUP with a single child, which repeats An array. The name Port does not appear
Owner, with two children GROUP with different children An object, with one key per child
Notes >> TEXT A string, with the lines separated by \n
  • Without a definition, 80 and true would be text, and nothing would tell a list from a node with a single child.
  • The comment is not exported: it is not part of the tree of the document.
  • The root node does not appear: the JSON is the content of Server.

By contrast, the Ports node in the canonical tree of STXT-TREE-SPEC, which is [80, 443] in the export:

{
	"name": "Ports",
	"canonicalName": "ports",
	"namespace": "com.example.servers",
	"form": "inline",
	"value": "",
	"children": [
		{
			"name": "Port",
			"canonicalName": "port",
			"namespace": "com.example.servers",
			"form": "inline",
			"value": "80",
			"children": []
		},
		{
			"name": "Port",
			"canonicalName": "port",
			"namespace": "com.example.servers",
			"form": "inline",
			"value": "443",
			"children": []
		}
	]
}

3.2 Import

Import is the way back. It receives the JSON above and the root node it must produce, Server (com.example.servers), and returns this document:

Server (com.example.servers):
	Name: web-01
	Active: true
	Ports:
		Port: 80
		Port: 443
	Owner:
		Person: Ana Ruiz
		Email: ana@example.com
	Notes >>
		Restart after every deployment.
		Do not switch off during office hours.

The definition supplies what the JSON does not carry:

  • The name Port of every element of the Ports array.
  • The namespace of every node.
  • The form of every node: Notes is written as a >> block because its text has more than one line and TEXT allows both forms.

The imported document has the same tree as the original. Only the comment has been lost.

4. An example: fill of Slots

This section is not normative. It is a first sketch of Slots and of how they combine.

A document with Slots:

Order (com.example.orders): $number$
	Date: $date$
	Currency: EUR
	Customer: {customer}
		Name: $name$
		Email: $email$
		# The phone is optional
		Phone: ?$phone$
	Line: [lines]$product$
		Quantity: $quantity$
		Price: $price$
		Note: ?$note$
	Shipment: [shipments]
		Carrier: $carrier$
		Parcel: [parcels]

The data, in JSON:

{
	"number": "2026-0142",
	"date": "2026-10-12",
	"customer": {
		"name": "Athena Bookshop",
		"email": "orders@athena.example"
	},
	"lines": [
		{ "product": "A5 notebook", "quantity": 40, "price": 3.25, "note": "Blue cover" },
		{ "product": "HB pencil", "quantity": 200, "price": 0.45 }
	],
	"shipments": [
		{ "carrier": "Royal Mail", "parcels": ["R-01", "R-02"] },
		{ "carrier": "DHL", "parcels": ["D-07"] }
	]
}

And the document that fill produces:

Order (com.example.orders): 2026-0142
	Date: 2026-10-12
	Currency: EUR
	Customer:
		Name: Athena Bookshop
		Email: orders@athena.example
	Line: A5 notebook
		Quantity: 40
		Price: 3.25
		Note: Blue cover
	Line: HB pencil
		Quantity: 200
		Price: 0.45
	Shipment:
		Carrier: Royal Mail
		Parcel: R-01
		Parcel: R-02
	Shipment:
		Carrier: DHL
		Parcel: D-07

The Slots of the example:

Slot What it does In the example
$var$ Puts the value of the data item var Date: $date$
{object} Enters the object object: the Slots of the node and of its children are looked up in it Customer: {customer}
[list] Repeats the node, with its children, once for every element of the array list Line, Shipment, Parcel
Leading ? Makes the Slot optional: if the data item does not exist, the node does not appear Phone: ?$phone$
  • If the element of an array is an object, fill enters it: every Shipment looks up its carrier and its parcels in its own element.
  • If the element is a value, it is the value of the node: Parcel: [parcels] produces Parcel: R-01 and Parcel: R-02.
  • A node can combine Slots: Line: [lines]$product$ repeats the node and puts in each one its product. [list] is evaluated first, then {object} and $var$ last.
  • A value with no Slots is copied as it is: Currency: EUR.
  • Every Slot is required, whether $var$, {object} or [list], unless it carries a leading ?: if quantity were missing in a line, or customer in the data, fill would fail.
  • Phone does not appear because the customer has no phone. Note appears in the first Line and not in the second.
  • An empty array produces no node and is not an error of fill. If the node was required, the validation of the filled document will say so.
  • A data item that does not fit its Slot is an error: an object where $var$ expects a value, or a value where [list] expects an array.
  • The comment does not pass to the filled document.
  • A document with Slots is not validated. The one that is validated is always the filled document.