This document describes how to produce a customization of the TEI
P5 schema. From the start, the TEI was intended to be used as a set of
building blocks for creating a schema suitable for a particular
project. This is in keeping with the TEI philosophy of providing a
vocabulary for describing texts, not dictating precisely what those
texts must contain or might have contained. This means that it is
likely, not just possible, that you will
want to have a tailored view of the TEI.
What do we mean by a customization? It is
important to understand that there is no single DTD or schema which is
the TEI; you always choose from the available modules (there are
currently 22 of them, listed in ) those
that you want, with the caveat that the three modules
core, header and
textstructure (and tei, when using
RELAX NG) should always be chosen unless you are certain you know what you are doing. Elements in these modules are referred to throughout
the other modules, and hence these modules cannot be eliminated without careful adjustments.
There are three ways of customizing the TEI:
Writing a high-level specification for a view of the TEI, and generating
an ad hoc DTD or schema; this is the preferred method.
Using the DTD modules, and specifying
in the document DTD subset which features you want activated. Using the RELAX NG modules, and writing a wrapper schema.
Note that it is not possible at present to use W3C Schema modules
for customization.
Although there is no default schema, TEI P5 does provide a number
of example customizations which may very well meet your needs, which can be downloaded from the TEI web site or from within the Roma interface:
tei_bare: TEI Absolutely Bareteilite: TEI Litetei_corpus: TEI for Linguistic Corporatei_ms: TEI for Manuscript Descriptiontei_drama: TEI with Dramatei_speech: TEI for Speech Representationtei_odds: TEI for authoring ODDtei_allPlus: TEI with maximal setup, plus external additionstei_svg: TEI with SVGtei_math: TEI with MathMLtei_xinclude: TEI with XInclude (experimental)tei_dictionaries: TEI for Dictionaries (experimental)
Choosing the basic set of modules may be sufficient, but it's also possible that you may want to tailor your TEI schema more tightly. For instance, once you have decided that your
application will make use of the msdescription and
linking modules, you may also want to
remove elements from some of the modules which you do not expect
to use, to reduce confusion and avoid the accidental use of elements you don't needrename elements (see for more discussion of
this)add, delete or change attributes for existing elements, perhaps to make the datatype stricter
add new elements, and insert them into the TEI class
system
We will be seeing examples of each of these in the following sections.
Below is a table of all of the TEI modules. More information about each one is given in the TEI Guidelines; each module corresponds to a single chapter.
The TEI modules.analysisSimple analytic mechanismscertaintyCertainty and uncertaintycoreElements common to all TEI documentscorpusHeader extensions for corpus textsdeclarefsFeature system declarationsdictionariesPrinted dictionariesdramaPerformance textsfiguresTables, formulae, and figuresgaijiCharacter and glyph documentationheaderThe TEI Headeriso-fsFeature structureslinkingLinking, segmentation and alignmentmsdescriptionManuscript DescriptionnamesdatesNames and datesnetsGraphs, networks and treesspokenTranscribed SpeechtagdocsDocumentation of TEI modulesteiDeclarations for datatypes, classes, and macros available to all
TEI modulestextcritText criticismtextstructureDefault
text structuretranscrTranscription of primary sourcesverseVerse structures
Writing ODD specifications
The TEI is written in a source format called ODD (One Document Does it All) which includes the schema fragments, prose documentation, and reference documentation for the TEI Guidelines in a single document.The concepts of ODD were devised and implemented by Lou
Burnard and Michael Sperberg-McQueen early in the development of the
TEI. The language developed over time as the TEI was put together, and
one form of it was documented in the TEI Guidelines (versions 3 and
4); unfortunately, that version of the markup was not what was
actually used to write the TEI Guidelines, which diverged into a more
complex scheme. For version 5 of the TEI, the entire ODD language was
heavily revised and simplified by a working group led by Sebastian
Rahtz, and the Guidelines themselves brought into conformance with
it.) An ODD specification is a normal TEI XML document which
makes use of the tagdocs module. This adds a series of
elements which are used to specify a new schema, and modifications to
the TEI element structure. It is described in detail in the TEI
Guidelines chapter
Documentation Elements, so only a
brief summary will be given here.
The recommended way to customize the TEI is to create a formal
specification expressing your customizations, as an XML document using TEI ODD markup;
this can then be compiled into a suitable DTD, RELAX NG schema or W3C Schema (together with the appropriate reference documentation),
using the Roma program. Roma is a web-based interface for creating TEI customizations,
which allows you to fill in simple forms to choose modules, add and delete elements, change attributes, and make other customizations. Advanced users can also create the ODD by hand using normal XML editing
tools.
If, however, you intend to make extensive use of the TEI in
conjunction with other schemas written in RELAX NG, working directly
with the RELAX NG modules is probably the best skill to learn. Typical
TEI users are more likely to work solely within the confines of the
TEI, and need to use DTDs and W3C Schema as well as RELAX NG, and so
writing customizations in the TEI's own language is usually
better.
There are several
important reasons why this high-level method is recommended:
It is independent of the schema type (DTD, RELAX NG schema, W3C schema) and the resulting specification can be used to generate a schema in any of these schema languages.It lets you document your work using the familiar TEI markup.It provides full access to the TEI class system.The Roma utilities generate a single,
portable, schema file which you can transfer to other people without
worrying about link dependencies.
A TEI schema is defined by a schemaSpec
element containing an arbitrary mixture of explicit declarations for
objects (i.e. elements, classes, or macro specifications)
and references to other objects containing such declarations. In
simplified form, the data model is
schemaSpec =
(moduleRef | elementSpec | macroSpec | classSpec )*
where elementSpec, macroSpec and classSpec
contain definitions of TEI objects. moduleRef references groups
of existing definitions, in one of two ways:
If the key attribute is provided, it refers to
the TEI name for a module, and details of that are accessed from the
TEI web service database (which may be a local installation).If the url attribute is provided, it refers to an
external file of schema definitions in the RELAX NG language (this is
used to pull in non-TEI schemas)
In the simplest case, a user-defined schema might simply combine
all the declarations from some nominated modules:
<TEI>
<teiHeader>
<fileDesc>
<titleStmt>
<title>TEI with simple setup</title>
<author>Sebastian Rahtz</author>
</titleStmt>
<publicationStmt><p>freely available</p></publicationStmt>
<sourceDesc>
<p>Written from scratch.</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<schemaSpec ident="oddex1" start="TEI">
<moduleRef key="header"/>
<moduleRef key="core"/>
<moduleRef key="tei"/>
<moduleRef key="textstructure"/>
</schemaSpec>
</body>
</text>
</TEI>
Note that this is a normal TEI document, with a metadata header.
In the other examples that follow, we will usually omit the outer TEI
wrapper and just show the schemaSpec element.
An ODD processor, given such a document, will combine the
declarations which belong to the named modules, and deliver the result
as a schema of some requested type. It might also generate documentation for
all (and only) the elements declared by those modules.
The start attribute of schemaSpec is used to
specify in a RELAX NG schema which elements are valid entry points.
You can address individual elements or classes of modules by the
adding elementSpec, classSpec or macroSpec
elements after moduleRef. Each of these must have a
mode attribute on it, which can take four values:
the object is entirely new. the object entirely replaces the existing
object with the same ident.all references to the original object with the same
ident are removed from the schema.child elements of the
object which appear in the original specification are replaced by
the versions in the new specification. This may be at any level, as we
will see in examples below.
It is
an error to provide replace, delete or
change versions for objects which do not already exist
in the TEI, and an error to add something with the same
ident attribute as an existing object in the TEI.
Adding new elements
A schema can include declarations for new elements, as in
the following example:
<schemaSpec xmlns:rng="http://relaxng.org/ns/structure/1.0"
ident="oddex1.5" start="TEI" xml:base="examples/odd1.5.xml">
<moduleRef key="header"/>
<moduleRef key="core"/>
<moduleRef key="tei"/>
<moduleRef key="textstructure"/>
<elementSpec ident="soundClip" mode="add">
<classes>
<memberOf key="model.pPart.data"/>
</classes>
<content>
<rng:text/>
</content>
</elementSpec>
</schemaSpec>
A declaration for the element soundClip, which is not defined in the TEI
scheme, will be added to the output schema. This element will also be added to
the existing TEI class model.pPart.data, and will thus be
avilable in TEI conformant documents.
In the following example
we add a new element rebirth which is modelled on the existing
birth element:
<schemaSpec xmlns:rng="http://relaxng.org/ns/structure/1.0"
ident="oddex4" start="TEI" xml:base="examples/odd4.xml">
<moduleRef key="header"/>
<moduleRef key="core"/>
<moduleRef key="tei"/>
<moduleRef key="textstructure"/>
<moduleRef key="corpus"/>
<elementSpec ident="rebirth" mode="add">
<gloss>Rebirth details</gloss>
<desc>contains information about a soul's rebirth, such as its date
and place.</desc>
<classes>
<memberOf key="model.persEventLike"/>
<memberOf key="att.editLike"/>
<memberOf key="att.datable"/>
<memberOf key="att.naming"/>
</classes>
<content>
<rng:ref name="macro.phraseSeq"/>
</content>
</elementSpec>
</schemaSpec>
There are usually four parts to such an
element definition:
An identifier (in this case the value rebirth for
the ident attribute).Documentation (the gloss and desc
elements)Declaration of which classes this element is to be a member of
(att.datable
and att.naming); this is the same as birth,
which we have to find out by looking at the definition of that The content model for the element, here the general purpose
pattern macro.phraseSeq
There is no need to specify a module for the element to appear in, as
this would not be used for anything.
Removing elements
Specifing that we do not want some of the elements to appear in
our final schema is easy:
<schemaSpec ident="oddex2" start="TEI" xml:base="examples/odd2.xml">
<moduleRef key="header"/>
<moduleRef key="core"/>
<moduleRef key="tei"/>
<moduleRef key="textstructure"/>
<elementSpec ident="headItem" mode="delete" module="core"/>
<elementSpec ident="headLabel" mode="delete" module="core"/>
<elementSpec ident="hyphenation" mode="delete" module="header"/>
</schemaSpec>
Note that no child elements of the deleted object are needed, or taken
notice of.
Changing existing elements
When we come to changing existing elements, the
specification looks a little more complex:
<schemaSpec ident="oddex3" start="TEI" xml:base="examples/odd3.xml">
<moduleRef key="header"/>
<moduleRef key="core"/>
<moduleRef key="tei"/>
<moduleRef key="textstructure"/>
<elementSpec ident="div" mode="change">
<attList>
<attDef ident="type" usage="req" mode="change">
<gloss>You must indicate the level of the
section</gloss>
<datatype>
<rng:ref xmlns:rng="http://relaxng.org/ns/structure/1.0" name="datatype.Code"/>
</datatype>
<valList type="closed" mode="replace">
<valItem ident="section">
<gloss>1st level section</gloss>
</valItem>
<valItem ident="subsection">
<gloss>2nd level section</gloss>
</valItem>
<valItem ident="subsubsection">
<gloss>3rd level section</gloss>
</valItem>
</valList>
</attDef>
</attList>
</elementSpec>
</schemaSpec>
In this example, we are changing the behaviour of the div
element so that the type attribute (inherited from the
class att.divLike) is mandatory and chosen from a fixed
set of values. The change value for mode
must be supplied on each identifiable part of the object which is to
change. So the elementSpec itself is in change
mode, plus the attDef for type, while the
valList is in replace mode. The elements we
have not specified any change for
(examples, references, etc) are copied from the
original.
Change mode can apply to classes as well as elements. In the
following example, we remove a set of attributes which are provided
for any element which is a member of the att.linking class:
<schemaSpec ident="oddex5" start="TEI" xml:base="examples/odd5.xml">
<moduleRef key="header"/>
<moduleRef key="core"/>
<moduleRef key="tei"/>
<moduleRef key="textstructure"/>
<moduleRef key="linking"/>
<classSpec module="linking" ident="att.global.linking" mode="change">
<attList>
<attDef ident="corresp" mode="delete"/>
<attDef ident="synch" mode="delete"/>
<attDef ident="sameAs" mode="delete"/>
<attDef ident="copyOf" mode="delete"/>
<attDef ident="next" mode="delete"/>
<attDef ident="prev" mode="delete"/>
<attDef ident="exclude" mode="delete"/>
<attDef ident="select" mode="delete"/>
</attList>
</classSpec>
</schemaSpec>
If you want to change which elements belong to
add.linking, you must change the classes
element of each of the elements separately.
Adding new elements in in a different namespace
A good example of this would be if you wanted to use the W3C XInclude
scheme in your XML. This is a way of referring to external files to be
transcluded (DTD users will be familiar with the use of file entities
to perform this job). This document, for example, pulls in a
table (created by an automatic process) by using this piece of code:
]]>
Since the include could occur anywhere, we want to add it to
a TEI class which is referenced almost everywhere;
model.inter does this job nicely. We could pull in an
external schema which defines include, but it may be amusing
to define it ourselves using this elementSpec:
<elementSpec xmlns:rng="http://relaxng.org/ns/structure/1.0"
ident="xinclude" mode="add" ns="http://www.w3.org/2001/XInclude" xml:base="examples/odd6.xml">
<altIdent>include</altIdent>
<classes>
<memberOf key="model.common"/>
</classes>
<content>
<rng:optional>
<rng:element name="fallback" ns="http://www.w3.org/2001/XInclude">
<rng:zeroOrMore>
<rng:element>
<rng:anyName/>
<rng:zeroOrMore>
<rng:attribute>
<rng:anyName/>
</rng:attribute>
</rng:zeroOrMore>
</rng:element>
</rng:zeroOrMore>
</rng:element>
</rng:optional>
</content>
<attList>
<attDef ident="href" usage="req">
<datatype>
<rng:data type="anyURI"/>
</datatype>
</attDef>
<attDef ident="parse">
<datatype>
<rng:choice>
<rng:value>xml</rng:value>
<rng:value>text</rng:value>
</rng:choice>
</datatype>
<defaultVal>xml</defaultVal>
</attDef>
<attDef ident="xpointer">
<datatype>
<rng:text/>
</datatype>
</attDef>
<attDef ident="encoding">
<datatype>
<rng:text/>
</datatype>
</attDef>
<attDef ident="accept">
<datatype>
<rng:text/>
</datatype>
</attDef>
<attDef ident="accept-charset">
<datatype>
<rng:text/>
</datatype>
</attDef>
<attDef ident="accept-language">
<datatype>
<rng:text/>
</datatype>
</attDef>
</attList>
</elementSpec>
Note the new ns attribute on elementSpec
which says that this element is not to be defined in the default (TEI)
namespace, and the use of the shorthand RELAX NG method of inline
element definition of fallback within the include
element.
Processing your ODD specification
When you have finished writing your customization, you can turn your ODD into schemas
or DTDs for use with XML editors or validators, or create schema
documentation showing the specification for your elements and
classes. Both of these tasks are the job of the
Roma family of software. This consists of a set
of XSLT transformations to manipulate ODD XML files, a script to run
them in the right way (see ), and a
web-based application (see ) to help
you develop the ODD XML and run the transformations.
Working with RELAX NG schema modules
If you want to use the RELAX NG schema modules,Examples of RELAX NG in this section are presented
using the compact syntax; when you write TEI customizations in the
ODD system, it is necessary to use the XML syntax. you must always
write a wrapper schema, selecting the appropriate modules. Thus a minimal TEI
schema might look like this:
namespace ns1 = "http://www.tei-c.org/ns/1.0"
namespace rng = "http://relaxng.org/ns/structure/1.0"
include "http://www.tei-c.org/schema/relaxng/header.rnc" inherit = ns1
include "http://www.tei-c.org/schema/relaxng/core.rnc" inherit = ns1
include "http://www.tei-c.org/schema/relaxng/tei.rnc" inherit = ns1
include "http://www.tei-c.org/schema/relaxng/textstructure.rnc" inherit = ns1
start = TEI
This is clearer than the DTD method, as it loads files
containing definitions from explicit URLs. It is then possible to override
any patterns in the included files; so the following schema
namespace ns1 = "http://www.tei-c.org/ns/1.0"
namespace rng = "http://relaxng.org/ns/structure/1.0"
include "http://www.tei-c.org/schema/relaxng/header.rnc" inherit = ns1
[ define [ name = "mentioned" notAllowed [ ] ] ]
include "http://www.tei-c.org/schema/relaxng/core.rnc" inherit = ns1
include "http://www.tei-c.org/schema/relaxng/tei.rnc" inherit = ns1
include "http://www.tei-c.org/schema/relaxng/textstructure.rnc" inherit = ns1
start = TEI
loads the header module, but then redefines the meaning of
mentioned to be the special RELAX NG pattern
notAllowed. This is a powerful and elegant mechanism; the
only downside is that you must understand the inner structure of the
TEI modules.
RELAX NG patterns are defined for the TEI as follows:
Each element, macro and class identifies the module it is part
of; this determines which schema file its definition is written to.Every macro (defined by a macroSpec in the source) has
a RELAX NG pattern of the same name. e.g.
macro.glossSeq = altIdent?, equiv*, gloss?, desc?
This can be redefined as desired.
Class specifications generate a number of patterns, depending on
their type:
An attribute class generates a pattern which references
the definition of each of the class attributes.Each attribute generates a pattern.A model class generates a pattern with an initial value of
notAllowed
Thus the att.timed attribute class generates
tei.timed.attributes =
tei.timed.attribute.start,
tei.timed.attribute.end,
tei.timed.attribute.dur
tei.timed.attribute.start =
attribute start { datatype.uri }?
tei.timed.attribute.end =
attribute end { datatype.uri }?
tei.timed.attribute.dur =
attribute dur { xsd:duration }?
while the
model.listLike model class generates
model.listLike = notAllowedEvery element generates at least three patterns; the first
defines the element itself, the second defines its content, and the third its
attributes. For example, the top-level element TEI is defined with:
TEI =
element TEI { TEI.content, TEI.attributes }
TEI.content = tei.teiHeader, tei.teiText
TEI.attributes =
[ a:defaultValue = "5.0" ] attribute version { xsd:decimal }?,
[ a:defaultValue = "TEI" ] attribute TEIform { text }?
Each of these can be redefined
separately. In addition, for each model class of which the element is
a member, it generates an addition to the class pattern. Thus
biblItem is a member of the
model.biblLike,
att.declarable, and
att.typed classes, so it produces:
tei.bibl |= biblItem
tei.declarable |= biblItem
tei.typed |= biblItem
so that any reference to model.biblLike will now allow for
biblItem too.
Working with the DTD subset
It is also possible to work with DTD modules,
although the TEI does not recommend this any more.
You specify which modules of the TEI you want
to use by means of the DTD internal subset. A minimal TEI
document using this method might start as follows:
]>
]]>
This loads the obligatory modules header,
core, and textstructure by setting the
corresponding parameter entity to INCLUDE.
There is a parameter entity for each module(created by prefixing
the module name with TEI., so we could request
the linking module to be loaded by adding
]]> to the DTD
subset. It is also possible to disable particular elements from the
modules by setting a parameter corresponding to the element. So
]]> would remove
ab from the list of allowed elements. Although this type of
customization is useful, it is not possible to use the method to add
new elements, change attributes, or manipulate classes. That sort of
change requires a deeper understanding of writing DTD extensions,
beyond the scope of this introduction.
Roma (command line)
An ODD specification can be processed in a scripting environment
by using the roma command-line script. This takes
the form:
Usage: roma [options] schemaspec [output_directory]
options, shown with defaults:
--xsl=/usr/share/xml/tei/stylesheet
--teiserver=http://tei.oucs.ox.ac.uk/Query/
--localsource= # local copy of P5 sources
options, binary switches:
--doc # create expanded documented ODD (TEI Lite XML)
--lang=LANG # language for names of attrbutes and elements
--doclang=LANG # language for documentation
--dochtml # create HTML version of doc
--patternprefix=STRING # prefix relax patterns with STRING
--docpdf # create PDF version of doc
--nodtd # suppress DTD creation
--norelax # suppress RELAX NG creation
--noxsd # suppress W3C XML Schema creation
--noteic # suppress TEI-specific features
--debug # leave temporary files, etc.
By default the script creates DTD, XSD and RELAX NG schemas, each
of these can be suppressed if needed, and a set of summary
documentation can be created. The xsl and
teiserver
options point to resources which roma needs to do
its job; if you have a local copy of the TEI XSL stylesheets, or a
local TEI eXist database, you can make the script independent of web access.
For information on using the web-based interface to roma, see Creating Customizations with Roma.
Making use of non-TEI schemas
The TEI was designed to capture all the vagaries of literary and
linguistic text; it does not attempt to describe other
specialised descriptive languages, such as those for chemistry,
mathematics, and vector graphics, or the technical vocabulary of
fields like law, health care and computer science. Some of the areas
have been addressed as thoroughly as the TEI in their own
standards. But what if we want to write a composite document mixing
material from two fields? Since all the TEI elements are in their own
XML namespace, it is easy to write a document which interleaves TEI
markup with markup from another namespace, as in this example of TEI
and Docbook:
<p>
The button on our web page shows the the date of the manuscript:
<guibutton xmlns:dbk="http://docbook.org/docbook-ng">
<date calendar="Julian" when="1732-02-22">Feb. 11, 1731/32, O.S.</date>
</guibutton>
Note that the representation is as found in the text, not normalized.
</p>
But what about validating this XML against a schema? Using the
Namespace-based Validation Dispatching Language (see ), we can validate the two languages
separately, but we also want
a TEI customization which checks where insert of
foreign
elements is permitted.
This means importing another schema, and changing one or more TEI
classes to allow for the new element(s). If it is also required that
TEI elements be allowed inside the elements of the other namespace,
we also have to modify the other namespace.
Two common cases which do not require interleaving are:
redefining the content of formula to
allow for MathML markup.redefining the content of figure to allow SVG
markup.
In each case, we first need a moduleRef which loads the
external schema in RELAX NG format: ]]>
These schemas can be downloaded from and ; note that they may each need a
small fix to remove the RELAX NG start pattern, as this causes
a conflict with the TEI definition. These define respectively two
patterns called mathml.math and svg.svg, which we
can proceed to add to TEI content models.
For MathML, we can redefine an existing macro which
is already provided as a hook inside the content of formula:
<macroSpec xmlns:rng="http://relaxng.org/ns/structure/1.0" type="pe"
ident="datatype.Formula" mode="change" xml:base="examples/addmath.xml">
<content>
<rng:ref name="mathml.math"/>
</content>
</macroSpec>
For SVG, we need to change the model of figure, simply
adding a reference to svg.svg at the end of a choice list:
<elementSpec ident="figure" mode="change" xml:base="examples/addsvg.xml">
<content>
<rng:zeroOrMore xmlns:rng="http://relaxng.org/ns/structure/1.0">
<rng:choice>
<rng:ref name="model.Incl"/>
<rng:ref name="figure"/>
<rng:ref name="figDesc"/>
<rng:ref name="graphic"/>
<rng:ref name="head"/>
<rng:ref name="p"/>
<rng:ref name="svg.svg"/>
</rng:choice>
</rng:zeroOrMore>
</content>
</elementSpec>
Internationalisation
A common requirement for changing existing elements is
to make the visible names suit a local language.
If we want to use the TEI in an entirely Spanish-speaking
environment, it can be useful to have a copy of the TEI schema
with all the names converted to Spanish. Documents can be created
and edited using this schema, and then translated back to the
canonical form for long-term archiving or distribution.
These translations are possible because the TEI
defines names in English for elements and attributes, but does not use
these names directly in content models for other elements. This means
that the names can be changed without breaking the rest of the
system. For example, the content model for series is
series.content =
(text
| model.gLike
| title
| editor
| respStmt
| biblScope
| model.global)*
but the title here refers to the pattern called
title; this is defined with:
title = element title { title.content, title.attributes }
If we change it to
title = element titulo { title.content, title.attributes }
the definition for series will still work, and the pointers
to the content and attributes of title remain correct.
If we create documents using this schema, how can we be
sure the back translation is easy? Because we can always
go back to the source of the customization to find the original name.
The translation process in ODD is simple. Each element or attribute
affected must be supplied in change mode, with simply
an altIdent provided. For example, here are some translations
into Spanish:
<schemaSpec xml:base="examples/spanish.xml">
<elementSpec ident="quote" module="core" mode="change">
<altIdent type="lang">cita</altIdent>
</elementSpec>
<elementSpec ident="cit" module="core" mode="change">
<altIdent type="lang">citaCompl</altIdent>
</elementSpec>
<elementSpec ident="mentioned" module="core" mode="change">
<altIdent type="lang">mencionado</altIdent>
</elementSpec>
<elementSpec ident="when" module="linking" mode="change">
<altIdent type="lang">cuando</altIdent>
<attList>
<attDef mode="change" ident="unit">
<altIdent type="lang">unidad</altIdent>
</attDef>
</attList>
</elementSpec>
</schemaSpec>
Notice that each attDef element must also specify
change mode, as well as the parent elementSpec.
Constructing specifications like this by hand is both tedious and
error-prone, and it would be unwise for each separate project to make
its own translations. The TEI Consortium therefore maintains a set of
translated names,A project initiated by Alejandro
Bia, and extended by Sebastian Rahtz and Arno Mittelbach. and a utility to generate the appropriate ODD code for
elements from all the modules you have selected. The
Roma application automates this to choosing from a drop
down list as shown in the figure below.
Choosing language for names in Roma
The effect of using a translated schema is shown in the image below; the oXygen editor is
shown editing
Hamlet with Spanish element and attribute
names.
Editing TEI text using a schema translated to Spanish