STXT vs XML

XML is the closest format to STXT: a tree of named nodes, namespaces and schemas. STXT aims for the same, in a document that can be written and read by hand.

The same content, twice

The header of an article in XML:

<article xmlns="http://example.com/articles">
	<title>Modern Software &amp; Architecture</title>
	<published>2026-09-01</published>
	<author email="ana@example.com">Ana López</author>
	<summary>
		A survey of monoliths, microservices
		&lt;and everything in between&gt;.
	</summary>
</article>

And in STXT:

Article (com.example.articles): Modern Software & Architecture
	Published: 2026-09-01
	Author: Ana López
		Email: ana@example.com
	Summary >>
		A survey of monoliths, microservices
		<and everything in between>.

It is the same tree, with the same idea of namespace. The differences are these:

XML STXT
End of a node Closing tag The indentation
Characters < and & Escaped (&lt;, &amp;) or placed in CDATA They mean nothing, any character is legal
Where a datum goes In an attribute or in a child element Always in a child node
Entities Internal and external None
Schemas DTD, XSD, RELAX NG, Schematron @stxt.schema and @stxt.template, written in STXT

Escapes and entities

XML reserves < and & in content. Text is escaped, or wrapped in a CDATA section, which in turn cannot contain ]]>.

Entities also open two well-known attacks:

  • External entities (XXE): they read files or reach the network.
  • Entity expansion: it exhausts memory.

Hardened parsers disable those features. STXT does not have them: there are no entities, references or inclusion (STXT-SPEC §15).

Attributes and elements

XML offers two places for a datum, attribute or child element. Each vocabulary decides, and whoever reads it has to look at both:

<server name="db1" host="10.0.0.5" port="5432">
	<timeout unit="s">30</timeout>
	<replica host="10.0.0.6"/>
	<replica host="10.0.0.7"/>
</server>

In STXT there are only nodes. What was an attribute or an element in XML is here, in both cases, a child:

Server: db1
	Host: 10.0.0.5
	Port: 5432
	Timeout: 30
		Unit: s
	Replica: 10.0.0.6
	Replica: 10.0.0.7

XML attributes are more compact on one line. STXT gives that up in exchange for a single form.

Validation

An XSD for the article from the beginning:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://example.com/articles"
           xmlns="http://example.com/articles"
           elementFormDefault="qualified">
	<xs:element name="article">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="title" type="xs:string"/>
				<xs:element name="published" type="xs:date"/>
				<xs:element name="author" maxOccurs="unbounded">
					<xs:complexType>
						<xs:simpleContent>
							<xs:extension base="xs:string">
								<xs:attribute name="email" type="xs:string" use="required"/>
							</xs:extension>
						</xs:simpleContent>
					</xs:complexType>
				</xs:element>
				<xs:element name="summary" type="xs:string" minOccurs="0"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

And the STXT template, written in the language itself and with the shape of the document it describes:

Template (@stxt.template): com.example.articles
	Structure >>
		Article (com.example.articles):
			Published: (1) DATE
			Author: (+)
				Email: (1) EMAIL
			Summary: (?) TEXT

They are not fully equivalent, and the difference goes in both directions:

  • The XSD validates more: the order of the children (xs:sequence), patterns, ranges and derived types. STXT schemas do not validate order, and have no regular expressions or conditional rules (STXT-SCHEMA-SPEC §11).
  • The template checks that Email is an email address, and xs:string does not.
  • The model of the template is closed: any undeclared child is an error.
# ERROR: this document does not validate
Article (com.example.articles): Modern Software & Architecture
	# `September 1st` is not a DATE
	Published: September 1st
	Author: Ana López
		# `ana` is not an EMAIL
		Email: ana
	# `Editor` is not in the template
	Editor: Joan Costa