STXT Templates (@stxt.template)
1. Introduction2. Terminology
3. Relationship between STXT and Template
4. General structure of a Template
5. One template per target namespace
6. `Structure >>` block
7. Cardinalities
8. Types
9. ENUM and value list
10. Namespaces within `Structure`
11. Rules of “defined nodes”
12. Compilation to Schema (semantic equivalence)
13. Template Errors
14. Conformance
15. Meta-template of the `@stxt.template` system itself
16. Normative examples
17. Appendix A — Grammar (informal)
18. End of Document
1. Introduction
This document defines the specification of the STXT Template language, a mechanism for describing semantic rules (structure, types, cardinalities, and allowed values) applicable to STXT documents.
A template:
- Is an STXT document whose namespace is
@stxt.template. - Is associated with a target namespace, analogously to a schema.
- Describes the expected structure through a
Structure >>block with simplified syntax. - Can be compiled into a semantically equivalent
@stxt.schemadocument within the subset expressible by templates.
Relationship with @stxt.schema:
- An implementation MAY support only schemas, only templates, or both.
- If both exist (schema and template) for the same target namespace, a conforming implementation SHOULD establish a consistent prioritization criterion.
- For a specific validation, an implementation MUST use a single effective semantic source: either schema or template.
- STXT core MUST NOT impose semantics: templates are an optional layer, subsequent to parsing the STXT document.
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.
Additional definitions:
- Target namespace: the STXT namespace to which the template applies (for example
com.example.docs). - Node template: an entry within the
Structure >>block that defines a node (and optionally its type/cardinality and its children). - Type: a semantic validation label (for example
TEXT,DATE,ENUM) equivalent to the types in STXT Schema. - Cardinality: a rule that defines how many times a child node may appear with respect to its parent.
3. Relationship between STXT and Template
Validation through templates occurs after STXT parsing:
- Parsing the STXT document into a hierarchical structure.
- Resolving the effective namespace of each node.
- Selecting the corresponding template for the target namespace.
- Applying template rules (structure, cardinality, types, values).
An implementation MAY apply rules during parsing, provided that this validation remains loosely coupled to the base parser.
4. General structure of a Template
A template document MUST have as its root node:
Template (@stxt.template): <target_namespace>
The template MUST contain exactly one Structure node in block form (>>).
Template (@stxt.template): com.example.docs Description: Example template Structure >> Document (com.example.docs): Title: (1) Body: (1) TEXT
Rules:
- The root node
TemplateMUST belong to the@stxt.templatenamespace. <target_namespace>MUST be a valid namespace according to STXT-SPEC (namespaces section).- The template document MAY include a
Descriptionnode. - There can only be one effective template per target namespace in a specific validation (see section 5).
5. One template per target namespace
For each logical namespace:
- There MUST NOT be more than one effective template simultaneously.
- If there are several candidate templates for the same namespace, the implementation SHOULD have a clear, stable, and deterministic criterion to decide which one applies.
- For a specific validation, an implementation MUST NOT apply several templates at the same time over the same target namespace.
6. `Structure >>` block
The Structure >> block defines a tree of node templates using indentation, where:
- Each non-empty line defines a node template.
- Indentation defines child nodes (just like STXT), but inside
Structure >>a data document is not being described, but rather an expected structure. - The indentation rules of the base STXT document apply to the template document outside the block.
- The content of
Structure >>is interpreted through the template grammar defined in this document. - The hierarchy within
Structure >>MUST be built with the same consecutive indentation model as in STXT-SPEC.
6.1 Recommended style convention
For readability, it is recommended:
- 1 tab per level.
- A single space between components.
- Maintain consistency in names (use the same capitalization/diacritics as in real documents).
6.2 Syntax of a `Structure` line
Each line of the Structure >> block has the form:
<NodeName> [<NamespaceOverride>] ":" [<RuleSpec>]
where:
<NodeName>is the name of the node (human text; it is normalized according to STXT-SPEC for comparison).<NamespaceOverride>is optional and has the form(<namespace>)or(@special.namespace)and defines the effective namespace of that template node.":"is mandatory (to be a valid STXT document).<RuleSpec>is optional and includes, in this logical order:- Optional cardinality (in parentheses).
- Optional reference to a previously defined node through
@Node Name, or alternatively a type. - Optional values if the type is
ENUM.
Examples:
Title: Title: (1) Body: (1) TEXT Color: (?) ENUM [red, green, blue] Body Content: (?) @Body Content Metadata (org.example.meta): (0,1)
Notes:
- If
<RuleSpec>is omitted completely, default cardinality and default type are assumed (sections 7 and 8). - A template node may have children even if it declares the default type
INLINE. Types that prohibit children are defined in section 8. - A reference
@Node NameMUST NOT be combined with an explicit type on the same line.
6.3 Parsing rules for `Structure >>`
A template parser MUST:
-
Read the
Structure >>block as a sequence of lines (already canonicalized by STXT core: right trim per line). -
Ignore empty lines.
-
Calculate hierarchy by indentation (same principles as STXT: consecutive indentation, without jumps).
-
For each line, parse:
- Node name + optional namespace
(ns)if present. - The mandatory
:character. - The optional rule specification (
RuleSpec).
- Node name + optional namespace
-
Resolve the effective namespace of each line.
-
Resolve
@Node Namereferences only against nodes already previously defined in the same template.
A template parser MUST fail if a line does not contain :.
6.4 Redefinition of nodes and nodes from other namespaces
Templates distinguish between:
- Local node definition: first appearance of a node whose effective namespace belongs to the target namespace of the template.
- Local node reference: reuse of a previous local definition through
@Node Name. - External reference: appearance of a node whose effective namespace belongs to another namespace.
Rules:
- A local node MUST NOT be defined more than once per pair
canonical name + effective namespace. - If a local node appears again in another part of
Structure, it MUST be done through a@Node Namereference. - A
@Node Namereference MUST point to a previous local definition in the same template. - A
@Node Namereference MAY override cardinality, but MUST NOT redefine type,ENUMvalues, or children. - Nodes from other namespaces MUST NOT be defined locally within the current template.
- An external node MAY appear several times, but on that line its cardinality ONLY SHOULD be declared.
Example:
Template (@stxt.template): com.example.dokumentando.doc Structure >> Document (com.example.dokumentando.doc): Title: (1) Sections: (*) Section: (+) TEXT Description: (1) TEXT Document Type: (1) Metadata (org.example.meta): (?) Summary (com.example.dokumentando.doc): Title: (1) @Title Content: (1) TEXT Metadata (org.example.meta): (?)
7. Cardinalities
Cardinality applies per instance of the parent node, counting only direct children that match by:
- Canonical node name (according to STXT-SPEC).
- Effective namespace of the node.
Cardinality is expressed as an optional token in parentheses: ( ... ).
7.1 Allowed forms
Allowed forms:
| Form | Meaning |
|---|---|
num |
Exactly num. |
* |
Any number (0..∞). |
+ |
One or more (1..∞). |
? |
Zero or one (0..1). |
num+ |
num or more (num..∞). |
num- |
Up to num (0..num). |
min,max |
Between min and max. |
Rules:
num,min, andmaxMUST be non-negative integers.- In
min,max,min <= maxMUST hold. +is equivalent to1+.?is equivalent to0,1.- The default cardinality, if omitted, is
*.
7.2 Default cardinality
If cardinality is not specified, the default value is:
*(any number).
8. Types
Types in templates reuse the set of types from STXT Schema, with the same intent: validate the form of the value and, optionally, its content.
The type is specified as a word after the cardinality (if present).
Examples:
Date: (1) DATE Body: (1) TEXT Is Public: (1) BOOLEAN
General rules:
- The explicit type MUST match exactly one of the types supported by the implementation.
- If a line uses a
@Node Namereference, it MUST NOT also declare an explicit type. - The semantic rules of types
INLINE,GROUP,BLOCK,TEXT,ENUM,NUMBER,DATE, etc. MUST be consistent with those defined in STXT-SCHEMA-SPEC.
8.1 Default type
If the type is omitted, the default type is:
INLINE
8.2 Compatibility with children
A conforming implementation MUST apply these rules:
-
BLOCK-only types (for example
BLOCK,TEXT,BASE64, etc.) ARE NOT compatible with children. If a template node has children inStructure >>and its effective type is BLOCK-only, the template MUST be considered invalid. -
GROUP types (or equivalent structural types without value) DO allow children.
-
INLINE types (for example
INLINE,NUMBER,DATE,BOOLEAN,ENUM, etc.) MAY allow children (same philosophy as Schema). Value validation applies to the node, and structure validation applies to its children.
8.3 Set of types
The recommended set of types is the same as STXT-SCHEMA-SPEC.
A template implementation:
- MUST support at least:
INLINE,GROUP,BLOCK,TEXT,NUMBER,BOOLEAN,DATE,ENUM. - SHOULD support the rest of the types defined in STXT Schema (for example
INTEGER,NATURAL,TIME,TIMESTAMP,UUID,URL,EMAIL,BASE64, etc.).
9. ENUM and value list
If the type is ENUM, the template MUST declare a list of allowed values, with at least one value.
The value list is specified with brackets [...] after the type:
ENUM [value1, value2, value3]
Color: (1) ENUM [red, green, blue]
Rules:
- If the type is
ENUM, the value list MUST exist for it to have valid content. - If the type is NOT
ENUM, a[...]list MUST be considered a template error. - Values are separated by commas
,. - Trim is applied (spaces/tabs) around each value.
- Value comparison MUST be done on the inline value already normalized through left/right trim.
- Value comparison MUST be exact and CASE-SENSITIVE.
- Comparison MUST NOT apply additional canonization, diacritic removal, or normalization equivalent to the canonical name of nodes.
- There must be at least one value in the list.
- Values MUST NOT be repeated after applying trim normalization.
10. Namespaces within `Structure`
Each line may include an explicit namespace for the template node:
Metadata (org.example.meta): (?)
Rules:
- If a
Structureline omits an explicit namespace, it inherits the effective namespace of its parent. - If the node has no parent within
Structure, the default namespace is the target namespace of the template. - Namespace inheritance works as in STXT data documents.
- If
(other.ns)is specified, that template node belongs to that other namespace. - If
(other.ns)is specified and that namespace is different from the target namespace, the line MUST NOT define children, explicit type, orENUMvalues; it MAY only declare cardinality.
11. Rules of “defined nodes”
In templates, a node becomes defined by its appearance in Structure.
Unlike Schema, there is no separate Node: section; the structure itself is the definition.
Rules:
- Every local node defined in
Structurebecomes part of the set of nodes in the template. - If a template references cross-namespace nodes, a complete validation system SHOULD have the corresponding template or schema for that external namespace if it wishes to validate those nodes deeply.
- An implementation MAY validate only cardinality and structure of the target namespace, treating cross-namespace nodes as a “black box”, according to configuration.
12. Compilation to Schema (semantic equivalence)
A template can be compiled into an equivalent schema:
- Each
Structureline generates aNodedefinition for the template node (in the corresponding namespace). - The indentation hierarchy in
StructuregeneratesChildren/Childin the schema. - Cardinality
( ... )in the template is translated to:Min/Maxin the schema.
- The type is copied to
Type. ENUM [a,b]is translated toValues/Value.- A
@Node Namereference reuses the definition already generated for that local node and only modifies the cardinality of the correspondingChild. - A cross-namespace node only generates a
Childreference; its definition corresponds to the template or schema of that other namespace.
Cardinality translation rules:
(num)→Min=num,Max=num(*)→ withoutMin, withoutMax(+)→Min=1(?)→Max=1(num+)→Min=num(num-)→Max=num(min,max)→Min=min,Max=max
13. Template Errors
A template is invalid if any of these conditions occurs:
- The
Structure>>document is not a valid STXT document (invalid indentation, etc.) - The document does not have root
Template (@stxt.template): <target_namespace>. Structure >>is missing orStructureis not a>>block.- A non-empty line within
Structuredoes not contain:. - Malformed cardinality or cardinality with invalid numbers.
- Unknown type (according to the set of types supported by the implementation).
- Use of
[...]if the type is notENUM. - BLOCK-only type with children defined in
Structure. - Redefining a local node that has already previously appeared without using a
@Node Namereference. - Using a
@Node Namereference that does not point to a previous local definition. - Declaring both a
@Node Namereference and an explicit type on the same line. - Declaring duplicate
ENUMvalues after trim normalization. - Defining children, explicit type, or
ENUMvalues in a cross-namespace node.
14. Conformance
A template implementation is conforming if:
- It implements the
TemplateandStructuregrammar of this document. - It applies the rules of cardinality, types,
@Node Namereferences, andENUM. - It applies the child compatibility rules by type.
- It rejects invalid templates according to section 13.
- It defines a stable template selection criterion (if multiple sources exist), without applying more than one simultaneously per target namespace.
15. Meta-template of the `@stxt.template` system itself
This section defines a recommended minimal template to validate documents in the @stxt.template namespace.
Template (@stxt.template): @stxt.template Structure >> Template (@stxt.template): (1) Description: (?) TEXT Structure: (1) BLOCK
Notes:
StructureisBLOCKbecause in templates it must be a>>block.Descriptionis optional and may beTEXT.
16. Normative examples
16.1 Simple template (one namespace)
Template (@stxt.template): com.example.docs Description: Simple template Structure >> Document (com.example.docs): Title: (1) Author: (1) Date: (1) DATE Body: (1) TEXT
16.2 Template with repetition and nested nodes
Template (@stxt.template): com.example.blog.post Structure >> Post (com.example.blog.post): Title: (1) Slug: (1) Published: (1) BOOLEAN Tags: (?) Tag: (+) Sections: (1) Section: (+) Heading: (1) Content: (1) TEXT
16.3 Template with ENUM
Template (@stxt.template): com.example.ui.theme Structure >> Theme (com.example.ui.theme): Name: (1) Mode: (1) ENUM [light, dark] Accent: (?) ENUM [blue, green, orange]
16.4 Template with local reuse
Template (@stxt.template): org.example.docs Structure >> Email (org.example.docs): Body Content: (1) TEXT Demo (org.example.docs): Body Content: (?) @Body Content
16.5 Cross-namespace (external references)
Template (@stxt.template): com.example.docs Structure >> Document (com.example.docs): Metadata (org.example.meta): (?) Content: (1) TEXT
In this case:
Metadatabelongs toorg.example.meta.- Deep validation of
Metadatawill depend on whether a schema/template exists fororg.example.meta.
17. Appendix A — Grammar (informal)
TemplateDoc = "Template" "(" "@stxt.template" ")" ":" NamespaceTarget { TemplateField }
TemplateField = DescriptionField | StructureField
DescriptionField = "Description" ":" Text
StructureField = "Structure" ">>" Newline { StructureLine }
StructureLine = Indent NodeSpec Newline
NodeSpec = NodeName [NsOverride] ":" [RuleSpec]
NsOverride = "(" ["@"] Namespace ")"
RuleSpec = [Card] [NodeRef | Type [EnumValues]]
Card = "(" CardToken ")"
CardToken = "*" | "+" | "?" | Num | Num "+" | Num "-" | Num "," Num
NodeRef = "@" NodeName
Type = IdentUpper
EnumValues = "[" Value { "," Value } "]"
NodeName = Text up to `(` or `:`, with trim and compaction of spaces
NamespaceTarget = Namespace according to STXT-SPEC
Namespace = Ident { "." Ident }
Ident = [a-z0-9]+
IdentUpper = [A-Z0-9_]+ ; recommended in uppercase (style)