This article was co-authored with generative AI. Facts have been checked against public documentation where feasible, but errors may remain. Please verify primary sources before relying on this for important decisions.
Audience: people who have started working with TEI/XML and want to clarify how ODD, XSLT, and Processing Model relate to each other. No need to be able to write XSLT or ODD from scratch.
When you start working with TEI/XML (Text Encoding Initiative — the international standard for structuring humanities texts), three terms appear: ODD, XSLT, and Processing Model. All three show up as files or scripts, which makes it hard to know "which one do I actually write?" or "do I pick one over the others?"
These three are not mutually exclusive alternatives — each handles a different job. This article uses minimal examples to clarify the roles and relationships among them.
The Three Roles at a Glance
The conclusion first, in table form.
| Name | What it does | Primary output |
|---|---|---|
| XSLT | Transforms XML into another format | HTML / PDF / other XML, etc. |
| ODD | Defines which TEI elements and attributes to use | Schema + specification document |
| Processing Model | Declares how each element should be rendered, inside an ODD | HTML (via a processor), etc. |
The important thing to avoid confusion: XSLT and ODD are different layers, and Processing Model is part of ODD. The relationship nests as follows:
ODD file (.odd — contents are TEI XML)
├── Schema definition section …… which elements/attributes are valid
└── Processing Model section …… how each element should be rendered (<model> elements)
XSLT file (.xsl) …… independent of ODD; contains transformation logic
The following sections cover each in turn. As a running example, assume this simple TEI/XML:
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader><!-- bibliographic information, etc. --></teiHeader>
<text>
<body>
<p><persName type="person">Natsume Soseki</persName> stayed in
<placeName>Matsuyama</placeName>.</p>
</body>
</text>
</TEI>
XSLT — Transforming TEI into Another Format
XSLT (XSL Transformations) is a W3C standard language for transforming XML into other formats. Since TEI/XML is not directly readable in a browser, it is commonly used to convert it to HTML.
For example, to convert TEI's <persName> (person name) element to an HTML <span>, you would write a template like this:
<xsl:template match="tei:persName">
<span class="person">
<xsl:apply-templates/>
</span>
</xsl:template>
The XSLT approach is to line up rules of the form "when this element appears, produce this output." XSLT has versions 1.0, 2.0, and 3.0; 1.0 runs with xsltproc, and 2.0 and later require processors such as Saxon.
XSLT lets you write transformation rules by hand, which gives high flexibility — but also means maintaining one stylesheet per output format (HTML, PDF, etc.).
ODD — Defining the Elements and Attributes to Use
ODD stands for "One Document Does it all," and it is how you describe a customization of TEI. Its content is written in TEI XML.
TEI defines hundreds of elements, but no single project uses all of them. ODD is where you record decisions like "this project uses only <persName>, <placeName>, and <date>" or "<persName>'s @type attribute only accepts the value person."
From an ODD you can generate two things:
- A schema (RELAX NG, etc.), which lets you mechanically validate that XML conforms to your project's rules
- A specification document — a human-readable record of how elements are used in the project
For instance, "the @type attribute on <persName> must be either person or place" is written in ODD like this:
<elementSpec ident="persName" mode="change">
<attList>
<attDef ident="type" mode="change">
<valList type="closed">
<valItem ident="person"/>
<valItem ident="place"/>
</valList>
</attDef>
</attList>
</elementSpec>
With this in place, a typo like <persName type="prson"> will be caught by schema validation. Unlike a prose manual that says "type should be person or place," the machine enforces it — that is the value of ODD.
Processing ODD involves tools such as the browser-based ODD editor Roma or the TEI Stylesheets command suite.
One important point: ODD does not produce HTML. ODD defines what constitutes valid XML; it does not produce display output. Rendering is handled by XSLT, or by the Processing Model described next.
Processing Model — Writing Rendering Declarations Inside ODD
Processing Model is a mechanism for declaring, inside an ODD, how each element should be rendered on output. It is not a separate file or technology — it is an <model> element added inside an <elementSpec> in ODD.
Where the schema definition section of ODD determines "what is valid XML," the Processing Model section determines "how that element should be presented."
<elementSpec ident="persName" mode="change">
<model behaviour="inline">
<outputRendition>font-weight: bold;</outputRendition>
</model>
</elementSpec>
The value of behaviour is chosen from a predefined vocabulary. The standard defines 26 behaviours:
| behaviour | Role |
|---|---|
alternate | Display multiple alternatives, switchable (e.g., sic/corr in critical editions) |
anchor | An anchor point marking a location in the text |
block | A block-level element with surrounding line breaks, like a paragraph |
body | The main body region of the document |
break | A page break, line break, or similar delimiter |
cell | A table cell |
cit | A citation (quoted text together with its source) |
document | The document as a whole |
figure | A figure |
glyph | A glyph or special character |
graphic | An image |
heading | A heading |
index | An index entry |
inline | An inline element flowing within surrounding text |
link | A hyperlink |
list | A list |
listItem | A list item |
metadata | Metadata (bibliographic information not normally displayed) |
note | A note |
omit | Omit from output (suppress) |
paragraph | A paragraph |
row | A table row |
section | A chapter, section, or similar structural unit |
table | A table |
text | A text string itself |
title | A title |
The behaviour data type is open in principle — processors can define additional behaviours — but these 26 are the standard recommended set. The predicate attribute enables conditional rendering, such as "apply this rendering only when @type is person."
Rendering instructions written here are read by a Processing Model-aware processor (TEI Publisher being the primary example) to generate HTML or other output. The idea behind Processing Model is to write declarations in ODD rather than hand-coding XSLT.
When to Use XSLT vs. Processing Model
Both XSLT and Processing Model are means of "converting TEI to HTML or similar" — this is where confusion is most likely. A rough guide:
| Writing XSLT directly | Using Processing Model | |
|---|---|---|
| Approach | Procedural transformation rules | Declarative statements inside ODD |
| Flexibility | High (any output is possible) | Constrained to the behaviour vocabulary |
| Best for | Complex layouts, faithful reproduction of specialized formats | Structurally standard documents, multi-format output |
| Learning curve | Requires learning XSLT | Requires understanding ODD and the behaviour vocabulary |
Because Processing Model uses a fixed vocabulary of declarations, a single set of declarations can cover multiple output formats (HTML, PDF, EPUB, etc.) at once. On the other hand, behaviour values express structural meaning (this is a paragraph, this is a heading), so they are less suited to fine-grained visual customization. For such cases, writing XSLT by hand is more straightforward. Based on what I have observed, XSLT tends to be chosen for use cases that require faithful reproduction of a specific page layout.
A typical workflow looks like this:
- Write an ODD to define the elements and attributes for the project (and generate a schema from it)
- Validate and encode the data (TEI/XML) against that ODD
- For display output, use Processing Model for structurally standard documents, or XSLT when precise visual control is needed
Common Misconceptions
- "ODD replaces XSLT" — it does not. ODD is for schema and specification; HTML is produced by XSLT or Processing Model.
- "Processing Model is separate from ODD" — it is not separate; it is a part of ODD (the
<model>element inside<elementSpec>). - "ODD is required to use TEI" — it is not. You can validate against the full TEI schema (TEI All). ODD is useful when you want to explicitly define and enforce project-specific rules.
To summarize once more: ODD defines "which components are permitted"; Processing Model is "rendering declarations written inside ODD"; XSLT is "transformation logic independent of ODD." Thinking of them as different layers with different responsibilities makes them easier to keep distinct.
Video version (auto-generated by AI): The content of this article is also available as a two-character dialogue explainer video, synthesized with VOICEVOX. As it is auto-generated, it may contain errors. Please refer to the article itself for accurate information.



Comments
…