Author Archives: Charles Riondet

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.

TEI Boilerplate: Displaying a facsimile beside a transcription

Charles Riondet, Inria

The TEI Boilerplate is a light framework to transform TEI P5 documents with a minimal XSLT stylesheet and present them in a browser, styled with CSS and Javascript. It has been developed by John Walsh, Grant Simpson and Saeed Moaddeli, from Indiana University.

The aim of this solution is to display directly the XML file, skipping the transformation in HTML. The usefulness of such a solution is obvious in order to have a rapid and clear human-readable version of a TEI document. However, TEI Boilerplate can also be a basis for more complex transformations and the production of extensive digital editions.

We would like to show here how we could use the TEI Boilerplate framework to visualize in the same page the edition of a manuscript and the digital image of the original document.
There are several ways to achieve the same result (or even an even more fancy result using elaborate Javascript instructions). Here is one of the simplest, which also gives a few hints of how the users could customize TEI Boilerplate according to their needs with average or even low programming skills.

The principle of TEI Boilerplate customization is very simple: the user can add any constraint in style instruction in two empty files: content/custom.xsl for XSLT processing and CSS/custom.css for styling. Here, we will use mainly the CSS file, but a minor changes in the XSLT templates can be done before.

Page breaks and facsimiles (optional)

What is follows a <pb/> corresponds to the content of a page. The image is associated to the  <pb/> element. TEI boilerplate rightly requires the use of the  @facs attribute to point to the URL of the image.

<pb facs="images/image1.png" n="1"/>

If you prefer to refer to your images in a <facsimile> element, you must modify an XSL template in the file content/teibp.xsl. But to make sure you know exactly the changes you made, I suggest that you copy the template in the file content/custom.xsl and make the change here.

The template to modify is called pb-handler :

<xsl:template name="pb-handler">
 <xsl:param name="n"/>
 <xsl:param name="facs"/>
 <xsl:param name="id"/>

 HERE, IT'S "TEI/facsimile/surface/graphic/@url"-->
 <xsl:variable name="facsUrl" select="//tei:surface[concat('#', @xml:id) = $facs]/tei:graphic/@url"/>
 <span class="-teibp-pageNum">
 <!-- <xsl:call-template name="atts"/> -->
 <span class="-teibp-pbNote">
 <xsl:value-of select="$pbNote"/>
 <xsl:value-of select="@n"/>
 <xsl:text> </xsl:text>
 <span class="-teibp-pbFacs">
 <a class="gallery-facs" rel="prettyPhoto[gallery1]">
 <xsl:attribute name="onclick">

<!-- replace the parameter $facs with the created variable $facsUrl -->

<xsl:value-of select="concat('showFacs(',$apos,$n,$apos,',',$apos,$facsUrl,$apos,',',$apos,$id,$apos,')')"/>

 <img alt="{$altTextPbFacs}" class="-teibp-thumbnail">

<!-- Replace also the value of the html attribute @src ( which is @facs), by the variable $facsUrl -->

<xsl:attribute name="src">
 <xsl:value-of select="$facsUrl"/>

CSS styling


To display side by side the transciption and the image, CSS instructions must be add in the custom.css file (CSS/custom.css)
The first widen the page.

 html {
 width: 90%;

Here, you shift the TEI boilerplate toolbox in the right corner of the page, or make it invisible

 #teibpToolbox {
 /* shift the toolbox in the right corner of the page */
 /* make the toolbox invisible */

Then, you can enlarge the image and make it float next to the text

 .-teibp-thumbnail {
 max-height: 1000px;

The following will delete the margin of the whole element containing the page number and the image, and align the tops of the transcripton and the facsimile.

 margin: 0em 0px;

Here, you can make changes to the way the page number is displayed.



These changes are very basic but efficient, and abides to the philosophy of TEI Boilerplate, that is to “largely preserve the integrity of the TEI document” ( For more elaborate CSS instructions, you can find a lot of documentation on websites such as

Download the TEI Boilerpalte on Github :
TEI document kindly provided by Magdalena Porst (FHP Potsdam).
Images from :
Institut national de recherche en informatique et en automatique (INRIA, Paris FR) . (2016). Journal intime de Leonore Alt [Corpus]. Disponible sur :