Category Archives: TEI

ODD topics – a simple introduction to attribute classes in TEI

Attribute classes have been introduced in the TEI infrastructure in order to declare groups of attributes which are shared across various elements. For instance, the att.timed attribute class contains the declaration of two attributes, @start and @end (see the elements whose specification states that they belong to this class will automatically get the two attributes. This is reflected in the generated documentation, as can be seen for the <u> element for instance (see

Over the years, it has been a general policy of the TEI technical council to factorise attribute declarations as classes in order to simplify the legibility and management of the guidelines.

When designing a TEI customisation in ODD, it is possible to use attribute classes to make the corresponding attributes available for additional elements. For example, you may want to say that there are several types of formulas in your document model and thus add the <formula> element to the att.typed attribute class.

In ODD specifications, adding an element to an attribute class can be achieved as exemplified below:

<elementSpec ident="formula" mode="change">
   <classes mode="change">
      <memberOf key="att.typed" mode="add"/>

The preceding declaration supplies the <formula> element with the two attributes declared in att.typed (see, namely @type and @subtype.

Conversely, one may want to get rid of some attributes inherited through a class on a specific element. There are actually two ways to do so:

  • Completely deselect the attribute class from the element, which takes out all attributes that were declared in the class;
  • Operates a surgical change by just taking out the intended attributes from the element.

The first method is similar to adding an attribute class to an element with the @mode attribute set to “delete” on <memberOf>. The following example removes the <s> element from the att.typed attribute class, thus depriving it of both @type and @subtype:

<elementSpec ident="s" mode="change">
   <classes mode="change">
      <memberOf key="att.typed" mode="delete"/>

The second methods elicits the deletion of the attribute from the element by using an <attDef> declaration. The following snippet deletes the @subtype attribute from the <s> element while keeping @type inherited from att.typed.

<elementSpec ident="s" mode="change">
      <attDef ident="subtype" mode="delete"/>

In some situations, when just one attribute from a class is needed, it is possible to combine a class attribution and attribute deletion declarations within the same ODD specification. For instance the following declaring makes <u> member of att.typed, while deleting @subtype:

<elementSpec ident="formula" mode="change">
   <classes mode="change">
      <memberOf key="att.typed" mode="add"/>
      <attDef ident="subtype" mode="delete"/>

Note: such a customization is closer to the spirit of the TEI guidelines, than declaring a new @type attribute on the element.

In the same way, it is possible to change the actual declaration of an attribute, in order to associate, for instance, a closed set of values to it.

ODD topics – Defining schematron constraints in ODD

Like any XML language, the TEI can be parsed with Schematron. Moreover, ODD supports natively the specification of Schematron rules,  and the TEI specification itself (for instance here: ) contains embedded schematron rules.

NB: This post doesn’t aim to explain how the Schematron language works. To learn more about Schematron, see W. Piez and D. Lapeyre, Introduction to Schematron, Mulberry Technologies, Inc, Nov. 2008. However, to minimally understand the following, you should know that Schematron, an ISO specification, is an XML language, based on the extensive use of XPath, that makes assertions or reports on the presence or absence of specific patterns in XML documents.

Schematron rules can be used to provide warnings without causing validation errors (i.e. “non-fatal errors”), or to add more qualitative rules to specific elements. For instance, one may want to set a character number limit for the content of a specific tag, or check the value of an attribute by means of a regular expression.

ODD makes it convenient to specify such rules at the same level of the element specification, in an element <constraintSpec>, possibly present in <attDef>, <classSpec>, <elementSpec>, or <schemaSpec> (see the TEI guidelines for more details). Inside <constraintSpec>, the <constraint> element contains assertions in the Schematron language, as shown in the following example:

<elementSpec ident="TEI" mode="change">
   <constraintSpec ident="xmlid" scheme="schematron" type="SSK">
         <sch:rule context="tei:TEI">
            <sch:let name="fileName" value="tokenize(document-uri(/), '/')[last()]"/>
            <sch:assert test="string(@xml:id)=substring-before($fileName, '.xml')" role="error">
The xml:id of the TEI element should be equal to the name of the file,
without the file extension. Currently the value of xml:id is "<sch:value-of select="@xml:id"/>" 
whilst the file name is "<sch:value-of select="$fileName"/>"</sch:assert>

Two important caveats (thanks to Syd Bauman’s XPath and Schematron for TEI Customization,

  1. the element <sch:rule> is not mandatory. When missing (i.e., just bare sch:assert and sch:report elements), the context of the Schematron rule is the element or attribute that is being defined (<elementSpec> or <attDef>).
  2. In <constraintSpec>, you need to specify the tei: prefix for TEI elements (see example below).

When a RELAX NG schema is generated from the ODD, the schematron rule will be embedded in the schema:

<define name="tei_TEI">
   <element name="TEI">
      <pattern xmlns=""
         <sch:rule xmlns=""
            <sch:let name="fileName" value="tokenize(document-uri(/), '/')[last()]"/>
            <sch:assert test="string(@xml:id) = substring-before($fileName, '.xml')" role="error">
The xml:id of the TEI element should be equal to the name of the file, 
without the file extension. Currently the value of xml:id is "<sch:value-of select="@xml:id"/>" 
whilst the file name is "<sch:value-of select="$fileName"/>"</sch:assert>

This embedded Schematron rule is checked in addition to the RELAX NG when performing file validation, as shown in the following images:

See the full ODD example under:

ODD topics – The Encoded Archival Description (EAD) 2002 ODD specification and the EHRI use case

Maintaining an XML specification with ODD can be useful outside the TEI realm. First, an ODD specification allows for a smoother maintenance and evolution of an XML vocabulary, but it is also a great help to document project-specific customizations and practices.

A recent and fully documented use case is the EAD specification and and its customization for the EHRI project. This use case has been described in two publications : Romary, L. & Riondet, C. Arch Sci (2018) 18: 165., and Romary, L. & Riondet, C. Umanistica Digitale (2019) 4: Data Sharing, Holocaust Documentation and the Digital Humanities: Best Practices, Case Studies and Benefits.

This work has shown the efficiency that can be gained by the use of ODD specifications for low-constrained vocabularies.

The official EAD schema and the official EAD tag library were encoded as an ODD document (with the agreement of the Library of Congress and the Society of American Archivists), in the context of the Parthenos project. This EAD ODD is a starting point for EHRI, and was used to create an EHRI-specific EAD profile with very precise content-oriented rules, based on EHRI requirements and on the data models of the collection holding institution. ODD also allows for the creation of qualitative documentation to be served to the user of conversion and validation services provided by the EHRI project.

EHRI EAD validation process

In EHRI, the EAD specification in ODD inherits everything from the generic EAD ODD except when a more specific behaviour is required by the project. However, the philosophy is to keep the EAD schema as it is. Instead, we use another validation language: ISO Schematron, an  ISO/IEC Standard (ISO/IEC 19757-3:2016) that parses XML documents and makes “assertions about the presence or absence of patterns”. It can be used in conjunction with a large number of grammar languages such as DTD, RELAX NG, etc.

ODD topics – adapting the TEI documentation with one’s own examples

Once the decision has been taken to build up an ODD schema that documents the usages of the TEI guidelines within a given digital humanities project, a first step towards customising the guidelines can be to adapt the documentation to reflect the specific practices of the project. A good way to do so is to work specifically on the examples associated to element description, which can easily be changed in the ODD specification.

Let us imagine we create a simple specification for a dictionary project, thus integrating the modules: core, tei, header, textstructure and dictionaries. We can add a specification that changes the element <entry> as follows:

<elementSpec ident="entry" mode="change">
      <egXML xmlns="">
               <entry xml:it="e-chat" xml:lang="fr">

What we have done here is basically two-fold:

  • Mark that we change the specification of the element by means of the @mode attribute set to “change” on the <elementSpec> element;
  • Introduce an <exemplum> element with the example we want to record for this element.

When compiled to create an XHTML output, all pre-existing examples for from the TEI guidelines are replaced by the one(s), that have been introduced that way (see screenshot below).

See the full ODD example under:

From TEI-XML to TXM, HTML and back

XSL Style Sheet – Strategy for an Import into TXM

Representations of the Other in the British, French and German Discourse on Europe: A Corpus-Based Contrastive Discursive Analysis

Naomi Truan (Université Paris-Sorbonne / Freie Universität Berlin)

The purpose of this article is to present a successful strategy to import the corpus on which my PhD project is based into the open source software TXM. If you still do not know TXM, click on the link! This software, developed at the Ecole Normale Supérieure (Lyon, France), is open source, regularly updated, and offers a wide range of textometric queries (among them cooccurrences and concordancies, but also many more).

The corpus is delivered with the TEI-XML files and two Stylesheets for the import and the conversion/visualisation in an HTML file (like new shampoos: 2-in-1!). The complete version of this document (with figures and two appendixes) is also to be found on the ORTOLANG server as a PDF document on my workspaces: French, English, German.

As a student in German Studies (focusing mainly on Literature, Philosophy, History, and Translation), I had no prior experience in the huge – but magnificent – world of Computational Linguistics. I discovered it through my PhD in Corpus Linguistics and thanks to the help of Laurent Romary and the TXM team (especially Serge Heiden, Alexey Lavrentev, and Bénédicte Pincemin). Thus, this article is not only here to show you how it works, but also to tell you: Yes, you can! Also with no idea on Computational Linguistics, you can acquire and develop your own strategies to make sense of these weird languages computer engineers work with.

My PhD thesis, entitled “Representations of the Other in the British, French and German Discourse on Europe: A Corpus-Based Contrastive Discursive Analysis”, relies on a qualitative and quantitative linguistic analysis of parliamentary debates in three European countries. You can find the corpora and their accurate description on ORTOLANG: French, English, German.

The corpus has been manually annotated according to the TEI Guidelines. If you wish to consult how the corpus was annotated, please see the document entitled “Corpus Annotation” on the ORTOLANG server (links above).

I – Import into TXM

To import the XML-TEI files into TXM, you have to follow the steps of an “Import TEI générique conservateur” and to select the Import XML/w +CSV. 

You have to put all the TEI-XML files into one folder and to add a file named (with no extension such as .doc, .pdf), in which you write ignoredelements=note|bibl. This way, the statistics of the corpus in TXM will not take into consideration (ignore) the TEI-XML tags <note> and <bibl>.

Then click on “Sélectionner le répertoire des sources” and select the corresponding folder. Please note that for your first import, the import.xml file, which is created during the import, will not be in the folder. If you happen to modify the TEI-XML files, the import.xml file will be recreated at each import.

In “Dossier des sources”, you can add information on the corpus. If you use the corpus I annotated for your own research project, I kindly ask you to refer to it in this section, for instance with following mention: Naomi Truan 2016 – CC BY 4.0.

The “Police d’affichage” depends on your personal taste and does not affect the import at all.

In the section “Langue principale”, do not forget to tick “en” for English, “de” for German, and “fr” for French if you wish to have the corpus syntactically annotated with TreeTagger (the tutorial for installing TreeTagger on TXM is here).

The “Paramètres du segmenteur lexical” do not need to be changed.

For the “Feuille XSL d’entrée”, please use the style sheet in an XSL format provided along with the TEI-XML files, freely adapted from txm-filter-teip5-xmlw-preserve.xsl.

“Editions” and “Commandes” do not need to be changed.

The import of the corpus can begin; you can now visualise the metadata of the corpus by clicking on the information icon.

Please note that the first “Propriétés des unités lexicales” (body, desc, incident, quote, seg) are not reliable; the given numbers do not correspond to anything in the corpus.

On the text level and on the utterance level, though, the information is fully accurate, so that the following metadata enable correct partitions of the corpus according to these variables: date, government, id, party, party-type, position, role, sex, who-party, who-party-type, who-position, who-role, who-sex.

II – HTML Visualisation of the Corpus with the XSL Style Sheet

I will now comment on the XSL Style Sheet, which can be used for the import into TXM (see Part I), but also to enable the visualisation of the corpus as a whole in an HTML-format. On the ORTOLANG server, you can find it under Content > UK TEI-XML Files, or here.

In the XSL Style Sheet, information in green such as <!– Corpus of British Parliamentary Debates –> does not impact on the XSL Style Sheet but simply provides information to guide the reader.

If you open the XSL Style Sheet and the XML Style Sheet together in oXygen XML Editor, and click, within the XML Style Sheet, on the red button on your right, then oXygen XML Editor will automatically run the Style Sheet and open the corpus in an HTML-format in your browser (like a webpage).

Alternatively, and if you have not proceeded to any changes in the corpus, just double-click on the “HTML file UK – Style sheet (2)”, which will automatically open in your browser as well. The procedure described above is necessary only if you wish to encode other tags or to visualise them differently (for instance, if you wish to see the <quote> tags in orange rather than in red) or if you add new tags in the corpus (for instance, if you notice a missing <quote> tag in one of the TEI-XML files of the corpus).

You can then scroll down through the corpus. It enables you a quick search (for instance through ctrl F for people not familiar with TXM, which offers much more queries in this regard) and a quick visualisation (for instance if you feel you have a better impression of the length of an utterance by seeing it on a webpage – how many lines? – rather than counting text units).

The corpus begins with general information, such as: Number of Incidents, Number of Turns, Number of Speakers, Number of Opposition Members, Number of Majority Members. In this regard, I strongly advise to rely on the statistics provided by TXM rather than on the XSL Style Sheet, which appears to be sometimes misleading. For instance, it counts seven Plaid Cymru Members but reports four names, which is inconsistent (there are, actually, fourPlaid Cymru Members):

Plaid Cymru Members: DAFIS – LLWYD – THOMAS – WIGLEY
Number of Plaid Cymru Members: 7
Number of Turns of Plaid Cymru Members: 7

This is it! Normally, every time you adjust the corpus (correct a typo, do some minor changes, rename a speaker, etc.), the HTML version will follow, enabling you to visualise the last version corpus very quickly and to search through it. At the same time, you can re-import the corpus into TXM by following the previous steps. If you do not rename the corpus, TXM will automatically ask you if you wish to replace the existing corpus. By clicking “yes”, you will update the corpus.

You now can see how to visualise (i.e. make nice!) your corpus through an XSL Style Sheet and an XML Style Sheet especially designed for the purposes of your own research. The Style Sheets can be adapted for every type of corpus following the TEI Guidelines. Thus, it should not be seen as a model, but rather as an example suitable for TXM.

Please feel free to contact me for any question regarding TXM, TEI, XML and HTML formats, but also Corpus Linguistics, Cognitive Linguistics, or Political Discourse! I cannot promise you to be able to answer every technical concern, but I will try my best (and can also forward your question(s) to people who know more than I do): Any comment will be much appreciated!

Next generation <etym> in the TEI – Putting together a proposal

After the discussion on the TEI list and the comments on the list, the post and twitter exchanges with @ttasovac, I came back to an old paper of Susanne Alt (, which provides an overview of the constraints that could apply to a comprehensive representation of etymological information in a dictionary entry.

Susanne uses the entry “Pamplemousse” from the TLF (Trésor de la Langue Française) to encode the following etymological information:

PAMPLEMOUSSE, subst. masc. […]

Empr. au néerl. pompelmoes, fém., au sens 1 a, qui est prob. pompel «gros, enlé» et de limoes «citron» (BOULAN, p.148; KÖNIG, pp.159-160). Apparaît d’abord dans des textes fr. qui le donnent comme mot néerl.: 1665 pompelmoes (J. LE CARPENTIER, L’Ambassade de la Compagnie orientale des Provinces Unies… [trad. d’un ouvrage néerl.], II, p.88 ds ARV.); 1666 pompelmous (M. THÉVENOT, Relation de divers voyages curieux… t.3 ds KÖNIG).

At the end of paper, following an in-depth discussion of etymons and links, which I advise you all to read, she suggests the following encoding:

(i.e. the lexical entry pamplemousse and its direct etymon pompelmoes) of the data structure in a TeI like format. Note that the basic building blocks for the characterization of a lexical entry (<form> and <sense>) are completely reus- able for the description of an etymon, and the language has been implemented as a standardized xml:lang attribute.

<lexicalEntry id=”LE1″>
<orth>pamplemousse</orth> …
<sense>… </sense>
<etymology> <etymon id=”LE2″>
<form> <orth xml:lang=”dutch”>pompelmoes</orth> <pos>commonNoun</pos> <gender>feminine</gender>
</form> <sense>
<glose>Citrus maxima</glose>
<note>probablement d’origine tamoule, De Vries, Nederl</note> </sense>
</etymon> <etymologicalLink source=”LE2″ target=”LE1″>
<etymologicalClass>loan word</etymologicalClass> </etymologicalLink>
</etymology> </lexicalEntry>

If we “modernize” this proposal to make it as close to a TEI compliant entry, we could think of something as follows:
<entry xml:id=”LE1″>
<orth>pamplemousse … </form>
<re type=”etymon” xml:id=”LE2″>
<orth xml:lang=”dutch”>pompelmoes</orth>
<gloss>Citrus maxima</gloss>
<note>probablement d’origine tamoule, De Vries, Nederl</note>
<link type=”loanWord” target=”#LE2 #LE1″/>

This is a little more ambitious than what was discussed in the previous post and related comments, but seems to follow what Toma Tasovac had in mind with an embedded entry in the description of the etymological content.

From print to code – multiple forms in one

An interesting discussion started on the TEI list ( about dictionary encoding, which I would like to reflect here to point to a couple of issues related to forms in dictionaries.

The post was sent by Susanna Allés, who is currently working on a Latin medieval dictionary. Here’s the initial question:

“we can’t find a satisfactory solution to encode a term (<term>) that corresponds to several languages. Here is the text:

arrencare  [cat. arrencar, arrancar (cf. oc., esp., port. arrancar), d’origen discutit | de origen discutido | of debated origin]  rompre roturar to break up: 1038 ACUrgell, Cart. I 357, f. 118, col. 2: terra quae fuit arrenchada qui est in Subuineas quae escamiauit Ermengauda a me Mirone. De una parte affrontat … in terra quae arrencauit … de IIII uero parte in ipsa fonnada de terra de Riamball que arrencauit.

The part in (square) brackets corresponds to the etymology (encoded with <etym>) and in red (cf. oc., esp., port. arrancar) corresponds to a term (the Romanic result); we want to relate this term with several languages (that it is, to Occitan, Spanish, Portuguese, in this case). Usually, if we are dealing with just a language, we encode it as <term xml:lang=”es”>arrancar</term> , but since we need to add other languages and the element term just allow one @xml:lang, we really don’t know how to handle.”

For sake of place, the original editor of the dictionary has used the same character sequence to represent three “words” from three different languages, which just happen, by chance (and linguistic proximity…), to be written in the same way.

The first line of thought, which considers the source text at face value may lead (like stated in the question) to  one could want to refer to three languages in relation to the sequence “arrancar”. Possibilities that have been alluded to on the list are:

  • putting more that one language codes as values for xml:lang, theoretically feasible, given the recent evolution of the corresponding W3C specification, not in the TEI though and probably an “interoperability nightmare” (quoting Stuart Yeates)
  • tagging the language references with <lang>, as suggested by Sabine Thuillier, in keeping to the basic constructs associated to <etym> (etymology) in the TEI guidelines (i.e. ​cf. ​<lang>oc., esp., port.</lang> <mentionned>arrancar</mentionned>​)​; Sabine rightly points to the fact that this solution is not optimal from a processing point of view.

Still, a more lexicographic analysis seems to lead to another path which consists in reconstructing the underlying logical representation, as nicely stated by Toma Tasovac:

“what we have here is typical lexicographic shorthand —  we know how lexicographers used to be stingy when it comes to space —  but that, if we really think about it, we are not (on the conceptual, modeling, even philosophical level) talking about one word being “the same” in three languages, but rather about three “different” words from three different languages that happen to have the same graphical representation.

What one could therefore also do is encode three instances of “arrancar” and each with an xml:lang for a different language.”

It is interesting to observe that several contributors, even being in line with this analysis, have actually suggested mechanisms to retain the “sameness” in the encoding (using @sameas, @exclude or <alt>; Syd Baumann actually provided quite a comprehensive set of possibilities)). No, Toma (supported by David Birnbaum) put it right:

“if one wanted to preserve the economic display in the end output, one would have to use XSLT or whatever one uses to check whether subsequent terms have the same graphical form and then display only one term, but display language ids from all of them.”

Which means that we need to produce an encoding where nothing may lead a processor to think that we have the “same” form, but it just happened that the three were printed out as one accidentally.

Finally, let me add that there is an issue with the encoding of “arrancar” as <term>. It is obviously a <form> (even better a <form>/<orth> if we anticipate that we could provide additional pronunciation information.

So my take at the encoding of this example would be as follows:

(cf. <lang>oc.</lang>, <lang>esp.</lang>, <lang>port.</lang> <form xml:lang=”oc”><orth>arrancar</orth></form><form xml:lang=”sp” ><orth>arrancar</orth></form><form xml:lang=”pt”><orth>arrancar</orth></form>)

But there is a hack here… <form> is not allowed there. Shall we change the content model of <etym>?

TBX goes TEI

As a first start into this blogging adventure, let me focus on a current activity which I started in the context of the recent ISO/TC 37 general meetings in Pretoria in June. The context is the ongoing revision process for ISO 300421.

Since its P4 edition, the TEI guidelines did not have a chapter on terminology any more. This is indeed missing since the current TEI dictionary chapter is covering semasiological views on lexical data (word to sense) and many applications require an onomasiological perspective (concept to term). For instance, translators, technical writers or language learners often manipulate terminologies, i.e. lexical structures are organised according to concepts, which in turn are subdivided in language sections (all words or expressions used to express the corresponding concept for this language) and then in term sections (all types of information needed to represent and qualify a given term). The underlying model is standardized  in ISO 16642 TMF2. TBX is thus a serialization of TMF.

I have now started to create an TEI/ODD specification that takes up the basic TBX structure, starting at <termEntry> level and allowing these to occur anywhere a traditional dictionary entry (<entry>) would in the TEI architecture.

To illustrate this, let me just show a typical  (yet awfully simple) example. The TBX namespace is a fake one (it is under discussion and we may want to get all this in the TEI name space).

<TEI xmlns=”″ xmlns:tbx=””

<termEntry xml:id=”c5″ xmlns=””>
<langSet xml:lang=”en”>
<langSet xml:lang=”fr”>


  1. ISO 30042:2008 Systems to manage terminology, knowledge and content — TermBase eXchange (TBX) []
  2. ISO 16642:2003 Computer applications in terminology — Terminological markup framework []