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.

NameWhat it doesPrimary output
XSLTTransforms XML into another formatHTML / PDF / other XML, etc.
ODDDefines which TEI elements and attributes to useSchema + specification document
Processing ModelDeclares how each element should be rendered, inside an ODDHTML (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:

behaviourRole
alternateDisplay multiple alternatives, switchable (e.g., sic/corr in critical editions)
anchorAn anchor point marking a location in the text
blockA block-level element with surrounding line breaks, like a paragraph
bodyThe main body region of the document
breakA page break, line break, or similar delimiter
cellA table cell
citA citation (quoted text together with its source)
documentThe document as a whole
figureA figure
glyphA glyph or special character
graphicAn image
headingA heading
indexAn index entry
inlineAn inline element flowing within surrounding text
linkA hyperlink
listA list
listItemA list item
metadataMetadata (bibliographic information not normally displayed)
noteA note
omitOmit from output (suppress)
paragraphA paragraph
rowA table row
sectionA chapter, section, or similar structural unit
tableA table
textA text string itself
titleA 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 directlyUsing Processing Model
ApproachProcedural transformation rulesDeclarative statements inside ODD
FlexibilityHigh (any output is possible)Constrained to the behaviour vocabulary
Best forComplex layouts, faithful reproduction of specialized formatsStructurally standard documents, multi-format output
Learning curveRequires learning XSLTRequires 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:

  1. Write an ODD to define the elements and attributes for the project (and generate a schema from it)
  2. Validate and encode the data (TEI/XML) against that ODD
  3. 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.

References