STXT Schemas (@stxt.schema)
1. Introduction2. Terminology
3. Relationship between STXT and Schema
4. General Structure of a Schema
5. One schema per namespace
6. Closed content model
7. Node Definition (`Node:`)
8. Children (`Children:`) and cross-namespaces
9. Types
10. Cardinalities
11. Order of children
12. Normative Examples
13. Schema Errors
14. Conformance
15. Schema of the Schema (`@stxt.schema`)
16. End of Document
1. Introduction
This document defines the specification of the STXT Schema language, a mechanism for validating STXT documents through formal semantic rules.
A schema:
- Is an STXT document with namespace
@stxt.schema. - Defines the nodes, types, and cardinalities of the target namespace.
- Does not modify the base syntax of STXT; it operates on the already parsed structure.
2. Terminology
The keywords "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" must be interpreted according to RFC 2119.
Terms such as node, indentation, namespace, inline and >> block retain their meaning in STXT-SPEC.
3. Relationship between STXT and Schema
Schema validation occurs after STXT parsing:
- Parsing the document into a hierarchical STXT structure.
- Resolving the effective namespace of each node.
- Applying the corresponding schema.
An implementation MAY apply validation during the parsing process, provided that such validation remains loosely coupled to the base parser. This allows errors to be detected before the full parsing is completed.
4. General Structure of a Schema
A schema document MUST have as its root node:
Schema (@stxt.schema): <target_namespace>
Rules:
<target_namespace>MUST be a valid namespace according to STXT-SPEC.- The root node
SchemaMUST belong to the@stxt.schemanamespace. - The schema document MAY include a
Descriptionnode. - The schema document MUST include one or more
Nodenodes.
Example:
Schema (@stxt.schema): com.example.docs
Description: Example schema
Node: Document
Type: GROUP
Children:
Child: Author
Child: Date
Max: 1
Child: Content
Min: 1
Max: 1
Child: Metadata (org.example.meta)
Max: 1
Node: Author
Node: Date
Type: DATE
Node: Content
Type: TEXT
5. One schema per namespace
For each logical namespace:
- There MUST NOT be more than one effective schema simultaneously.
- If an implementation has several candidate schemas for the same namespace, it SHOULD apply a clear and deterministic selection policy.
- For a specific validation, there MUST be only one effective schema.
6. Closed content model
STXT Schema uses a closed content model. This means that, for each node in the document, only the direct children explicitly declared in the schema are allowed.
Rules:
- If a
Nodedeclares aChildrenblock, its instances in the document MAY ONLY have as direct children the nodes declared throughChild(each identified by its logical paircanonical name + effective namespace). - If a
Nodedoes not declareChildren, its instances in the document MUST NOT have any direct children (total closure). - The appearance of an undeclared direct child MUST cause a validation error.
This model is consistent with the STXT philosophy of failing loudly: a misspelled
node (for example Titel instead of Title) is detected as an undeclared child instead
of being silently accepted.
Note on evolution. Since the model is closed, adding a node to a namespace is a
change that breaks validation of documents using old schemas. The recommended practice
for evolving a namespace incompatibly is to version it in the namespace itself
(for example com.example.docs.v1 → com.example.docs.v2), so that each version has its
schema and documents declare the version they use.
Unresolved cross-namespace nodes. If a Child points to another namespace and the
implementation does not have a schema for that namespace, the declared node is accepted, but its
internal content remains unvalidated ("black box"). An implementation SHOULD be able
to distinguish between "fully validated" and "partially validated" in that case (see section 7.1).
7. Node Definition (`Node:`)
7.1 Basic form
Node: Node Name
Description: Node description
Type: Type
Children:
Child: Child Name. It may include a namespace if it is different from the target namespace
Min: optional, indicates the minimum number of children that may appear
Max: optional, indicates the maximum number of children that may appear
Rules:
- The inline value of
NodeMUST be a valid node name according to STXT-SPEC. - Each
NodeMUST be unique within the schema at the canonical name level. - Each
Nodedefines the semantics of the node in the schema's target namespace. - If
Typeis omitted, the default type isINLINE. - A
NodeMUST NOT contain more than oneDescriptionnode, more than oneTypenode, more than oneChildrennode, nor more than oneValuesnode. - Only types that allow children (see section 9) MAY declare
Children. DeclaringChildrenin a type that does not allow children MUST cause a schema error.
7.2 Values in ENUM types
Node: Node Name
Description: Node description
Type: ENUM
Values:
Value: value 1
Value: value 2
Value: value 3
The ENUM type, and only ENUM, MAY specify a Values node with the allowed values through Value nodes.
If Values exists, it MUST contain at least one Value node.
If a Node declares Type: ENUM, it MUST include Values.
Since ENUM does not allow children (section 9), a Node of type ENUM MUST NOT declare Children.
8. Children (`Children:`) and cross-namespaces
A node MAY have a Children entry.
If Children exists, it MUST contain one or more Child nodes with the information of the allowed children.
A Child MAY belong to another namespace, in which case it is indicated in the name of the Child itself.
Example:
Node: node name
Children:
Child: child name (child.namespace)
Min: 0
Max: 1
- If the namespace is omitted, the
Childbelongs to the target namespace of the current schema. - If an explicit namespace is indicated, the
Childbelongs to that specific namespace. - Within the same
Childrennode, an implementation MUST NOT accept twoChildnodes that point to the same logical paircanonical name + effective namespace.
8.1 Explicitly defined nodes
Every node that appears in Children must have its own definition as Node: in its corresponding schema.
This avoids "ghost" children and guarantees that all nodes have defined semantics.
This implies:
- If
Child: Metadata (org.example.meta)appears, then there MUST be a schema fororg.example.metaand within it there MUST beNode: Metadata. - An implementation MAY defer this check until the moment of document validation, but the schema remains semantically incomplete until such definition exists.
9. Types
Types define:
- The form of the node value (inline,
>>block, both, or none). - Whether the node allows children.
- Content validation.
They are defined inside Node, through a Type element. Example:
Node: node name
Type: NODE_TYPE
Children:
Child: Child Name
9.1 Model of two independent properties
Each type is described through two independent properties:
- Value form:
INLINE,BLOCK,INLINE/BLOCKorNONE. - Allows children: YES or NO.
These two properties are independent from each other. In particular, "allows children" is not derived from the value form. The compatibility rule is deliberately simple:
Only the two generic structural types — INLINE and GROUP — allow children. All
types with specific content validation are leaves (they do not allow children).
The intuition: as soon as a type declares that it validates a specific datum (NUMBER, DATE,
BOOLEAN, ENUM, etc.), that node is a datum, and a datum is a leaf. If both
value and structure are needed, the generic INLINE type is used, which exists precisely for that;
and if only structure is needed, GROUP is used.
Other considerations:
- The type does not control requiredness; only the form and validity of the value. Requiredness of appearance is controlled through cardinality.
- The value of
TypeMUST match exactly one of the types defined in this section. - Declaring
Childrenin aNodewhose type does not allow children MUST cause a schema error.
9.2 Basic structural types
A conforming implementation MUST support these types and MUST validate their structure.
| Type | Value form | Allows children | Description / Validation |
|---|---|---|---|
| INLINE | INLINE | YES | Inline : text. Default type. Optional value without specific validation. Allows children. |
| GROUP | NONE | YES | Does not allow textual value. Structured children only. |
| BLOCK | BLOCK | NO | >> text block only. Does not allow children. |
| TEXT | INLINE/BLOCK | NO | Generic text. It may be inline : or >> block. Does not allow children. |
9.3 Basic INLINE content types
A conforming implementation MUST support these types and MUST validate their structure.
| Type | Value form | Allows children | Description / Validation |
|---|---|---|---|
| BOOLEAN | INLINE | NO | true or false. |
| NUMBER | INLINE | NO | Number in JSON format. |
| ENUM | INLINE | NO | Only specified values (see 9.6). |
9.4 Extended INLINE content types
A conforming implementation MUST support these types and SHOULD validate their structure.
| Type | Value form | Allows children | Description / Validation |
|---|---|---|---|
| INTEGER | INLINE | NO | Number without decimals (positive and negative). |
| NATURAL | INLINE | NO | Numbers greater than or equal to 0 without decimals. |
| DATE | INLINE | NO | YYYY-MM-DD date. |
| TIME | INLINE | NO | ISO 8601 time, hh:mm:ss. |
| TIMESTAMP | INLINE | NO | Full ISO 8601 timestamp. |
| UUID | INLINE | NO | Canonical UUID. |
| URL | INLINE | NO | Valid URL or URI. |
| INLINE | NO | Valid email address. |
9.5 Extended INLINE/BLOCK binary content types
A conforming implementation MUST support these types and MAY validate their structure.
| Type | Value form | Allows children | Description / Validation |
|---|---|---|---|
| HEXADECIMAL | INLINE/BLOCK | NO | [0-9A-Fa-f]+. Hexadecimal string. |
| BINARY | INLINE/BLOCK | NO | [01]+. Binary string. |
| BASE64 | INLINE/BLOCK | NO | Valid Base64 content. |
9.6 ENUM type
The ENUM type allows explicitly enumerating the values allowed for a node.
Rules:
- Comparison MUST be done on the inline value already normalized by left and right trim, as defined by STXT-SPEC.
- Comparison MUST be exact and CASE-SENSITIVE.
- Comparison MUST NOT apply additional canonicalization, removal of diacritics, nor normalizations equivalent to the canonical name of nodes.
- The node MUST define
ValueswithValuenodes, which represent the allowed values. - Each
ValueMUST be unique after inline normalization by trim. ENUMdoes not allow children: aNodeof typeENUMMUST NOT declareChildren.
Example:
Node: Node Name
Type: ENUM
Values:
Value: value 1
Value: value 2
Value: value 3
A conforming implementation MUST check ENUM types against their allowed values and MUST reject any value that does not match exactly one of them.
10. Cardinalities
Cardinalities are expressed through the Min and Max nodes within each Child.
They are optional non-negative integers that indicate the minimum or maximum number of allowed occurrences of that child.
Rules:
- If
Minis omitted, the effective minimum is0. - If
Maxis omitted, the effective maximum is unlimited. MinandMaxMUST NOT appear more than once within the sameChild.- If both exist,
MinMUST NOT be greater thanMax. - Cardinality applies per instance of the parent node.
- Cardinality counts only direct children with the same canonical name and the same effective namespace.
- Cardinality validation is independent of child order: it counts occurrences, not positions (see section 11).
- A conforming implementation MUST check cardinalities.
11. Order of children
STXT Schema does not validate the order of children. Validation of cardinality and presence is independent of the position of each child within its parent: it only counts how many times each child appears, not in what order.
Two documents with the same children in a different order validate exactly the same. This is a design decision consistent with the Human-First principle: the author of a document should not have to remember the order of the fields.
Order preserved, not validated. Although order is not validated, the order of appearance of children is preserved in the parsed tree (core guarantee, STXT-SPEC). Therefore, an application that needs positional meaning (for example, consecutive sections of a document) obtains it from the tree itself, not from validation. The semantics of order belong to the application.
Sequential order validation is an explicit non-goal of STXT Schema: introducing
ordered content models (in the style of xs:sequence) would considerably complicate
validators (automata, particle ambiguity) without a clear benefit for the target use cases.
12. Normative Examples
12.1 Schema with cross-namespace references
Schema (@stxt.schema): com.example.docs
Node: Document
Type: GROUP
Children:
Child: Metadata (org.example.meta)
Max: 1
Child: Content
Min: 1
Max: 1
Node: Content
Type: BLOCK
And in org.example.meta:
Schema (@stxt.schema): org.example.meta
Node: Metadata
Type: INLINE
12.2 Valid document
Document (com.example.docs):
Metadata (org.example.meta): info
Content>>
Line 1
Line 2
12.3 Recursive structure
The closed model allows recursion effortlessly: a Node may be declared as a child of itself
or of an ancestor.
Schema (@stxt.schema): com.example.docs
Node: Section
Type: GROUP
Children:
Child: Title
Min: 1
Max: 1
Child: Section
Node: Title
Type: INLINE
Here Section may contain more nested Section nodes at any depth (limited
by the recommended depth limit in STXT-SPEC, security section).
13. Schema Errors
A schema is invalid if:
- It defines two
Nodewith the same canonical name. - It uses an unknown
Type. - It defines
Childrenin aNodewhose type does not allow children (section 9). - Cardinality is invalid (
Min > Max, a value that is not a non-negative integer, duplicatedMin/Max). - A
Node: ENUMdoes not defineValues, orValuescontains noValue. - A duplicated
Valueappears after inline normalization by trim. - Two equivalent
Childnodes appear (samecanonical name + effective namespace) within the sameChildren. - A child appears in
ChildrenwhoseNodeis not defined in its corresponding schema.
A document is invalid against a schema if:
- A node presents a direct undeclared child in the
Childrenof its definition (closed model, section 6). - A node without declared
Childrenpresents any direct child. - A declared cardinality is violated.
- The value of a node does not satisfy validation of its type.
- An
ENUMvalue does not match exactly any of itsValue.
14. Conformance
An implementation is conforming if:
- It fully implements this document.
- It validates types, value forms, cardinalities, and allowed values (ENUM).
- It applies the closed content model (section 6).
- It applies the child compatibility rule by type (only
INLINEandGROUPallow children). - It applies the strict mandatory definition rule for all nodes referenced in
Children. - It validates cardinalities independently of order.
- It selects, for each validation, a single effective schema per namespace.
- It rejects invalid documents and schemas.
15. Schema of the Schema (`@stxt.schema`)
This section defines the official schema of the schema system itself: the meta-schema that validates all documents in the @stxt.schema namespace.
Level of guarantee. The meta-schema validates the form of a schema document (which nodes
exist, their types, their cardinalities). It cannot express the conditional or
crossed rules of this document (for example "Values only if Type: ENUM", or "Min ≤ Max"),
which belong to the language but not to the meta-schema. Therefore, "validating against the meta-schema"
is a necessary but not sufficient condition to be a valid schema: in addition, the rules of section 13 must be met.
15.1 Considerations
- Every schema document is:
Schema (@stxt.schema): <target-namespace> - A schema contains:
- Optionally a
Description. - One or more
Nodenodes.
- Optionally a
- Each
Node:- Has an inline value (the node name of the target namespace).
- May optionally have:
DescriptionTypeChildrenValues
- Each
Child(Childrenelement) defines the name (and optionally a different namespace) and may have:Min: Minimum number of nodes that must appear. If the node does not exist there is no established minimum.Max: Maximum number of nodes that may appear. If the node does not exist there is no established maximum.
- Each
Values:- May only appear in
Nodenodes of typeENUM. - Contains one or more
Valuenodes.
- May only appear in
- The names (
Schema,Node,Type,Children,Child,Description,Min,Max,Values,Value) belong to the@stxt.schemanamespace.
15.2 Complete Meta-Schema
Schema (@stxt.schema): @stxt.schema
Node: Schema
Children:
Child: Description
Max: 1
Child: Node
Min: 1
Node: Node
Children:
Child: Type
Max: 1
Child: Children
Max: 1
Child: Description
Max: 1
Child: Values
Max: 1
Node: Children
Type: GROUP
Children:
Child: Child
Min: 1
Node: Description
Type: TEXT
Node: Child
Children:
Child: Min
Max: 1
Child: Max
Max: 1
Node: Min
Type: NATURAL
Node: Max
Type: NATURAL
Node: Type
Type: ENUM
Values:
Value: INLINE
Value: BLOCK
Value: TEXT
Value: GROUP
Value: BOOLEAN
Value: NUMBER
Value: ENUM
Value: INTEGER
Value: NATURAL
Value: DATE
Value: TIME
Value: TIMESTAMP
Value: UUID
Value: URL
Value: EMAIL
Value: HEXADECIMAL
Value: BINARY
Value: BASE64
Node: Values
Type: GROUP
Children:
Child: Value
Min: 1
Node: Value
Note: in the meta-schema, Node and Child are of default type INLINE (their
inline value is the name of the target node or child) and therefore they allow children. This illustrates that
INLINE is the type that combines value and structure, the core of the system.
15.3 Quick reading
-
SchemaInline value = target namespace (e.g.com.example.docs). Children:Description(?),Node(*). -
NodeInline value = target node name (e.g.Document,Author). Optional children:Type: concrete type (if missing ⇒INLINE).Children: Node with list of allowedChild.Description: explanatory text.Values: Allowed values (ENUM type only).
-
TypeInline (ENUM), with the type name (GROUP,INLINE,NUMBER, etc.). -
ChildrenGROUP: contains one or moreChildnodes. -
DescriptionTEXT: may be inline or multiline. -
ValuesGROUP: contains one or moreValuenodes. -
ValueInline value with one of the allowed values for theENUM.
15.4 Minimal valid example
Schema (@stxt.schema): com.example.docs
Node: Document
15.5 Complete example
Schema (@stxt.schema): com.example.docs
Description: Example schema
Node: Document
Type: GROUP
Children:
Child: Title
Min: 1
Max: 1
Child: Author
Child: Metadata (org.example.meta)
Max: 1
Node: Title
Type: INLINE
Node: Author
Type: INLINE