Curso de XML para TEI

De la sintaxis XML al marcado filológico, el aparato crítico, la consulta con XPath y la publicación de ediciones digitales

Autor/a

Francisco Javier Muñoz Acebes

Fecha de publicación

21 de junio de 2026

Cómo usar este documento

Este material reúne doce lecciones progresivas, de la sintaxis XML más elemental hasta la publicación de ediciones TEI. Cada lección sigue la misma estructura:

  • un Objetivo breve;
  • el desarrollo de los conceptos, numerados internamente;
  • ejercicios y soluciones (las soluciones aparecen en un bloque plegable: inténtalo antes de mirarlas);
  • avisos sobre errores frecuentes;
  • un resumen de qué debes retener;
  • una tarea final.

Algunas lecciones incluyen además un bloque de código de práctica en Python (con lxml para las lecciones de XPath y transformación). Estas celdas son opcionales: no sustituyen a un editor XML como Oxygen, pero permiten manipular los mismos ejemplos en Google Colab, Jupyter o un chunk ejecutable de Quarto/RStudio.

Recomendaciones de trabajo:

  1. Lee cada lección en orden; las lecciones 7 a 12 dan por hecho lo aprendido en las lecciones 1 a 6.
  2. Resuelve los ejercicios antes de abrir la solución.
  3. Comprueba siempre tus archivos en Oxygen (o en otro editor/validador XML): primero la buena formación, después la validez TEI.
  4. Usa la hoja de referencia rápida del final como chuleta de consulta mientras trabajas.

Lección 1: Introducción a XML para empezar con TEI

NotaObjetivo

Al terminar esta lección entenderás qué es XML, cómo piensa un documento marcado y cómo crear un archivo mínimo sin errores de estructura.

Idea central

XML no sirve para dar formato visual, sino para representar la estructura y el significado de la información mediante etiquetas.

En TEI, eso significa que no marcas “esto va en cursiva”, sino “esto es un verso”, “esto es un título”, “esto es un nombre de persona” o “esto es una abreviatura”.

Conceptos básicos

  • Elemento: una unidad marcada con apertura y cierre, por ejemplo <titulo>Parzival</titulo>.
  • Atributo: información añadida dentro de la etiqueta de apertura, por ejemplo <verso n="12">...</verso>.
  • Elemento raíz: el contenedor único de todo el documento.
  • Texto: el contenido entre etiquetas.
  • Jerarquía: relación padre-hijo entre elementos.

Ejemplo mínimo

<poema>
  <titulo>Iwein</titulo>
  <autor>Hartmann von Aue</autor>
</poema>

Aquí poema es la raíz, y titulo y autor son hijos de poema.

Cómo leer XML

Piensa en XML como un árbol. En vez de mirar la página como lector final, la miras como editor de datos textuales: qué partes tiene el texto y qué función cumple cada una.

Por ejemplo, un poema puede descomponerse en obra, autor, estrofa y verso; XML permite declarar esas partes explícitamente para que luego puedan validarse, buscarse o transformarse.

Ejemplo algo más rico

<poema>
  <titulo>Erec</titulo>
  <autor>Hartmann von Aue</autor>
  <estrofa>
    <verso n="1">Uns ist in alten maeren</verso>
    <verso n="2">wunders vil geseit</verso>
  </estrofa>
</poema>

Eso todavía no es TEI, pero ya piensa como TEI: estructura textual antes que apariencia.

Reglas mínimas

Estas reglas no se negocian en XML bien formado:

  • Toda etiqueta abierta debe cerrarse.
  • Las etiquetas distinguen mayúsculas y minúsculas.
  • Los elementos deben anidarse correctamente.
  • Debe haber un solo elemento raíz.
  • Los atributos van siempre entre comillas.

Incorrecto:

<poema>
  <titulo>Iwein<título>
  <autor>Hartmann von Aue</autor>
</poema>

Incorrecto también:

<poema>
  <estrofa>
    <verso>Texto</estrofa>
  </verso>
</poema>

Correcto:

<poema>
  <estrofa>
    <verso>Texto</verso>
  </estrofa>
</poema>

Diferencia útil

“Bien formado” no significa todavía “válido”. Un XML bien formado solo cumple las reglas sintácticas generales; un XML válido además cumple las reglas de un esquema concreto, como una DTD o un esquema TEI.

TipTu primer ejercicio

Copia este texto en un archivo llamado poema.xml:

<?xml version="1.0" encoding="UTF-8"?>
<poema>
  <titulo>Der arme Heinrich</titulo>
  <autor>Hartmann von Aue</autor>
  <estrofa>
    <verso n="1">Ein ritter sô gelêret was</verso>
    <verso n="2">daz er an den buochen las</verso>
  </estrofa>
</poema>

Código de práctica (Python)

Estas celdas son opcionales: no sustituyen a Oxygen, pero permiten manipular los mismos ejemplos como texto dentro de un cuaderno Jupyter, Colab o un chunk de Quarto/RStudio.

xml_ejemplo_1 = '''<?xml version="1.0" encoding="UTF-8"?>
<poema>
  <titulo>Der arme Heinrich</titulo>
  <autor>Hartmann von Aue</autor>
  <estrofa>
    <verso n="1">Ein ritter sô gelêret was</verso>
    <verso n="2">daz er an den buochen las</verso>
  </estrofa>
</poema>'''

print(xml_ejemplo_1)
TipEjercicio guiado

Responde:

  1. ¿Cuál es el elemento raíz?
  2. ¿Qué elementos son hijos directos de <poema>?
  3. ¿Qué elemento tiene un atributo?
  4. ¿Cuál es el nombre del atributo?
  5. ¿Cuál es su valor?
  1. La raíz es <poema>.
  2. Sus hijos directos son <titulo>, <autor> y <estrofa>.
  3. El elemento con atributo es <verso>.
  4. El atributo se llama n.
  5. Sus valores son "1" y "2".
AdvertenciaErrores típicos
  • Cerrar mal una etiqueta.
  • Mezclar mayúsculas y minúsculas.
  • Olvidar comillas en un atributo.
  • Cruzar etiquetas por mala anidación.
TipMini práctica

Corrige este XML para que quede bien formado:

<poema>
  <titulo>Erec</titulo>
  <autor>Hartmann von Aue</autor>
  <estrofa>
    <verso n=1>Des was ein ritter wol bekant
    <verso n="2">an im was manegiu tugent</verso>
  </estrofa>
</poema>
<poema>
  <titulo>Erec</titulo>
  <autor>Hartmann von Aue</autor>
  <estrofa>
    <verso n="1">Des was ein ritter wol bekant</verso>
    <verso n="2">an im was manegiu tugent</verso>
  </estrofa>
</poema>
ImportanteQué debes retener

XML no describe cómo se ve un texto, sino qué es cada parte del texto.

Eso es exactamente lo que luego hará TEI, pero con un vocabulario académico más rico para describir documentos, textos, metadatos y fenómenos editoriales.

PrecauciónTarea final de la Lección 1
  • Escribe un XML propio de 8 a 10 líneas con raíz, título, autor y dos versos.
  • Introduce a propósito un error y comprueba si lo detectas.
  • Ábrelo en Oxygen o en otro editor XML y revisa si está bien formado.

Lección 2: Sintaxis XML sin errores

NotaObjetivo

En esta lección aprenderás a escribir XML sin errores de sintaxis. La meta es que puedas crear archivos bien formados de manera segura antes de pasar a la codificación propiamente TEI.

1. Qué significa escribir XML correctamente

Un documento XML correcto en el nivel más básico es un documento bien formado. Eso significa que respeta las reglas generales de sintaxis: un único elemento raíz, etiquetas cerradas, anidación correcta, coincidencia exacta entre apertura y cierre, y valores de atributos entre comillas.

Todavía no significa que sea TEI válido. Solo significa que el documento no está roto.

2. Las reglas obligatorias

Regla 1. Debe existir un único elemento raíz

Todo el documento debe quedar contenido dentro de un único elemento principal.

<poema>
  <titulo>Iwein</titulo>
  <autor>Hartmann von Aue</autor>
</poema>

Incorrecto:

<titulo>Iwein</titulo>
<autor>Hartmann von Aue</autor>

Regla 2. Toda etiqueta abierta debe cerrarse

Correcto:

<titulo>Erec</titulo>

Incorrecto:

<titulo>Erec

Regla 3. Las etiquetas son sensibles a mayúsculas y minúsculas

Correcto:

<verso>Texto</verso>

Incorrecto:

<verso>Texto</Verso>

Regla 4. Los elementos deben anidarse bien

Correcto:

<estrofa>
  <verso>Texto</verso>
</estrofa>

Incorrecto:

<estrofa>
  <verso>Texto</estrofa>
</verso>

La regla práctica es simple: el último elemento que abres debe ser el primero que cierras.

Regla 5. Los atributos deben ir siempre entre comillas

Correcto:

<verso n="1">Uns ist in alten maeren</verso>

Incorrecto:

<verso n=1>Uns ist in alten maeren</verso>

3. Atributos: qué son y cómo usarlos

Un atributo añade información al elemento, pero no sustituye el contenido.

<verso n="2">wunders vil geseit</verso>

Aquí: - verso es el nombre del elemento. - n es el nombre del atributo. - "2" es el valor del atributo. - wunders vil geseit es el contenido textual.

4. Caracteres especiales

En XML, algunos caracteres tienen significado estructural. Si quieres que aparezcan como texto, debes escaparlos.

  • < se escribe como &lt;
  • & se escribe como &amp;
  • > puede escribirse como &gt;
  • " puede escribirse como &quot;
  • ' puede escribirse como &apos;

Código de práctica (Python)

Estas celdas son opcionales: no sustituyen a Oxygen, pero permiten manipular los mismos ejemplos como texto dentro de un cuaderno Jupyter, Colab o un chunk de Quarto/RStudio.

nota_incorrecta = '<nota>2 < 3 y A & B</nota>'
nota_correcta = '<nota>2 &lt; 3 y A &amp; B</nota>'

print('Incorrecto:')
print(nota_incorrecta)
print()
print('Correcto:')
print(nota_correcta)

5. Declaración XML

Muchos archivos XML empiezan con una declaración como esta:

<?xml version="1.0" encoding="UTF-8"?>

Si la usas, debe ir al principio del archivo. UTF-8 es la codificación más habitual y recomendable.

6. Sangrado y espacios

El sangrado no cambia la estructura lógica del XML, pero ayuda muchísimo a leerlo.

<poema><estrofa><verso n="1">Texto</verso></estrofa></poema>
<poema>
  <estrofa>
    <verso n="1">Texto</verso>
  </estrofa>
</poema>

La segunda forma es mucho más legible.

AdvertenciaError típico: confundir estructura con visualización

Esto está mal pensado:

<cursiva>Parzival</cursiva>

si lo que quieres decir en realidad es que eso es un título.

Esto está mejor:

<titulo>Parzival</titulo>

8. Diagnóstico de errores frecuentes

Error A. Falta de cierre

<poema>
  <titulo>Iwein</titulo>
  <autor>Hartmann von Aue
</poema>

Error B. Cruce de etiquetas

<poema>
  <estrofa>
    <verso>Texto</estrofa>
  </verso>
</poema>

Error C. Atributo sin comillas

<verso n=4>Texto</verso>

Error D. Dos raíces

<titulo>Erec</titulo>
<autor>Hartmann von Aue</autor>
TipEjercicio guiado

Corrige este XML:

<?xml version="1.0" encoding="UTF-8"?>
<poema>
  <titulo>Erec</titulo>
  <autor>Hartmann von Aue</autor>
  <estrofa>
    <verso n=1>Des was ein ritter wol bekant</verso>
    <verso n="2">an im was manegiu tugent
  </estrofa>
</poema>
<?xml version="1.0" encoding="UTF-8"?>
<poema>
  <titulo>Erec</titulo>
  <autor>Hartmann von Aue</autor>
  <estrofa>
    <verso n="1">Des was ein ritter wol bekant</verso>
    <verso n="2">an im was manegiu tugent</verso>
  </estrofa>
</poema>
TipEjercicio autónomo

Determina cuáles de estos ejemplos son correctos y cuáles no.

A.

<l n="1">Texto</l>

B.

<l n="1">Texto</L>

C.

<lg>
  <l>Uno</l>
  <l>Dos</l>
</lg>

D.

<lg>
  <l>Uno</lg>
  <l>Dos</l>
  • A: correcto.
  • B: incorrecto, porque l y L no son lo mismo.
  • C: correcto.
  • D: incorrecto, porque hay mala anidación y además queda roto el conjunto.

11. Aplicación a TEI

Antes de aprender elementos TEI concretos como <TEI>, <teiHeader>, <text>, <body>, <div> o <l>, necesitas dominar estas reglas mecánicas. Si la sintaxis XML falla, el documento no se puede procesar bien.

ImportanteQué debes retener

Quédate con estas cinco comprobaciones rápidas:

  1. ¿Tengo una sola raíz?
  2. ¿He cerrado todo lo que abro?
  3. ¿He respetado mayúsculas y minúsculas?
  4. ¿He anidado bien los elementos?
  5. ¿Están los atributos entre comillas?
PrecauciónTarea final de la Lección 2
  1. Escribe un archivo XML de 10 a 12 líneas con un poema, dos versos y un atributo n en cada verso.
  2. Añade una nota con una comparación matemática, por ejemplo 2 < 5, y corrígela usando entidades XML.
  3. Ábrelo en Oxygen y localiza cualquier error de sintaxis.
  4. Guarda una segunda versión con un error intencionado y explica cuál es.

Bloque de práctica opcional en Python

Estas celdas no sustituyen a Oxygen, pero te permiten guardar ejemplos XML como texto dentro del cuaderno.

xml_practica = '''<?xml version="1.0" encoding="UTF-8"?>
<poema>
  <titulo>Práctica</titulo>
  <autor>Tu nombre</autor>
  <estrofa>
    <verso n="1">Primer verso</verso>
    <verso n="2">Segundo verso</verso>
  </estrofa>
</poema>'''

with open('practica.xml', 'w', encoding='utf-8') as f:
    f.write(xml_practica)

print('Archivo guardado como practica.xml')

Lección 3: Primer documento TEI

NotaObjetivo

En esta lección aprenderás la estructura mínima de un documento TEI completo. La meta es que pases de XML genérico a un archivo ya reconocible como TEI.

1. La idea central

Un documento TEI no es solo texto marcado: también incluye metadatos sobre ese texto.

Por eso, un documento TEI básico tiene dos grandes partes:

  • <teiHeader>: contiene los metadatos.
  • <text>: contiene el texto codificado.

2. Estructura mínima

La forma más básica de un documento TEI es esta:

<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Erec</title>
        <author>Hartmann von Aue</author>
      </titleStmt>
      <publicationStmt>
        <p>Edición de trabajo para aprendizaje TEI.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Transcripción de ejemplo basada en un testimonio medieval.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <p>Texto de prueba.</p>
    </body>
  </text>
</TEI>

3. Qué hace cada parte

<TEI>

Es el elemento raíz del documento TEI. Todo queda contenido dentro de él.

<teiHeader>

Describe el archivo: qué es, quién lo ha preparado, cómo se publica y de dónde procede el texto.

<fileDesc>

Es la descripción básica del archivo.

Dentro de <fileDesc> aparecen tres componentes muy importantes:

  • <titleStmt>: título y responsables.
  • <publicationStmt>: publicación o difusión del archivo.
  • <sourceDesc>: descripción de la fuente.

<text>

Contiene el texto propiamente dicho.

<body>

Es el cuerpo principal del texto.

4. Cómo leer este modelo

Piensa así:

  • <teiHeader> = información sobre el documento.
  • <text> = contenido del documento.

Es decir, TEI separa metadatos y texto.

5. Ejemplo comentado

Si codificas un fragmento de Iwein, el archivo TEI no solo debe incluir los versos o párrafos, sino también una descripción mínima de qué obra es y cuál es su fuente.

Por eso incluso un archivo TEI muy sencillo ya tiene una dimensión bibliográfica y editorial.

AdvertenciaError frecuente

Un error muy habitual al empezar con TEI es escribir solo esto:

<text>
  <body>
    <p>Texto de prueba</p>
  </body>
</text>

Eso puede parecer suficiente, pero no constituye un documento TEI completo, porque falta el elemento raíz <TEI> y falta el <teiHeader>.

TipMini práctica

Transforma este XML genérico:

<poema>
  <titulo>Erec</titulo>
  <autor>Hartmann von Aue</autor>
  <verso>Uns ist in alten maeren</verso>
</poema>

en un documento TEI mínimo.

<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Erec</title>
        <author>Hartmann von Aue</author>
      </titleStmt>
      <publicationStmt>
        <p>Documento de práctica.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Fragmento de prueba para aprendizaje TEI.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <p>Uns ist in alten maeren</p>
    </body>
  </text>
</TEI>
ImportanteQué debes retener

Quédate con esta plantilla mental:

  1. <TEI> envuelve todo.
  2. <teiHeader> describe.
  3. <text> contiene.
  4. <body> desarrolla el texto.
PrecauciónTarea final
  • Crea un documento TEI mínimo con una obra medieval de tu elección.
  • Cambia el contenido de <titleStmt>, <publicationStmt> y <sourceDesc>.
  • Añade dos párrafos dentro de <body>.

Lección 4: Estructura del texto en TEI

NotaObjetivo

En esta lección aprenderás a organizar el texto dentro de TEI. La meta es que sepas marcar divisiones, encabezados, párrafos y versos.

1. Del contenedor al contenido

En la lección anterior viste la carcasa general del documento TEI.

Ahora toca organizar el texto interno.

Dentro de <text> normalmente trabajarás con:

  • <body> para el cuerpo principal.
  • <div> para divisiones o secciones.
  • <head> para encabezados.
  • <p> para párrafos.
  • <lg> para grupos de versos.
  • <l> para versos individuales.

2. Divisiones del texto

El elemento <div> sirve para marcar una subdivisión del texto.

Puede representar, por ejemplo:

  • una parte,
  • un capítulo,
  • una sección,
  • un poema,
  • una escena.

Ejemplo:

<text>
  <body>
    <div type="chapter" n="1">
      <head>Primer capítulo</head>
      <p>Este es el primer párrafo.</p>
      <p>Este es el segundo párrafo.</p>
    </div>
  </body>
</text>

3. El elemento <head>

<head> se usa para encabezados o títulos internos.

No describe todo el documento, sino una unidad concreta dentro de él.

Por ejemplo, el título de un capítulo o de una sección.

4. Prosa en TEI

Cuando el texto es prosa, la unidad básica suele ser <p>.

Ejemplo:

<text>
  <body>
    <div type="prologue">
      <head>Prólogo</head>
      <p>Este es el primer párrafo del prólogo.</p>
      <p>Este es el segundo párrafo del prólogo.</p>
    </div>
  </body>
</text>

5. Verso en TEI

Cuando trabajas con poesía o textos versificados, TEI usa:

  • <lg> para un grupo de versos.
  • <l> para cada verso.

Ejemplo:

<text>
  <body>
    <div type="poem">
      <head>Erec</head>
      <lg type="stanza">
        <l n="1">Uns ist in alten maeren</l>
        <l n="2">wunders vil geseit</l>
        <l n="3">von helden lobebaeren</l>
        <l n="4">von grôzer arebeit</l>
      </lg>
    </div>
  </body>
</text>

6. Diferencia entre <p> y <l>

No debes usar <p> para versos ni <l> para prosa.

La elección del elemento depende de la naturaleza textual de la unidad que estás codificando.

  • Prosa: <p>
  • Verso: <l>
  • Grupo de versos: <lg>

7. Combinar estructura y género textual

Puedes tener un documento con divisiones generales y, dentro de ellas, prosa o verso.

Por ejemplo:

<text>
  <body>
    <div type="introduction">
      <head>Introducción</head>
      <p>Texto introductorio en prosa.</p>
    </div>
    <div type="poem">
      <head>Poema</head>
      <lg type="stanza">
        <l n="1">Primer verso</l>
        <l n="2">Segundo verso</l>
      </lg>
    </div>
  </body>
</text>
AdvertenciaError frecuente

Un error común es usar etiquetas genéricas sin reflejar la estructura real.

Por ejemplo, esto es pobre desde el punto de vista TEI:

<texto>
  <seccion>
    <titulo>Poema</titulo>
    <linea>Verso 1</linea>
    <linea>Verso 2</linea>
  </seccion>
</texto>

Está bien como XML inventado, pero no aprovecha el vocabulario TEI.

9. Reescritura en TEI

Una versión TEI sería:

<text>
  <body>
    <div type="poem">
      <head>Poema</head>
      <lg>
        <l n="1">Verso 1</l>
        <l n="2">Verso 2</l>
      </lg>
    </div>
  </body>
</text>
ImportanteQué debes retener

Quédate con esta lógica:

  1. <div> organiza grandes bloques.
  2. <head> nombra esos bloques.
  3. <p> marca prosa.
  4. <lg> agrupa versos.
  5. <l> marca cada verso.
PrecauciónTarea final
  • Crea una <div> con <head> y dos <p>.
  • Crea otra <div> con un <lg> y cuatro <l>.
  • Integra ambas en un mismo <body>.

Código de práctica (Python)

Estas celdas son opcionales: no sustituyen a Oxygen, pero permiten manipular los mismos ejemplos como texto dentro de un cuaderno Jupyter, Colab o un chunk de Quarto/RStudio.

tei_minimo = '''<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Iwein</title>
        <author>Hartmann von Aue</author>
      </titleStmt>
      <publicationStmt>
        <p>Documento de práctica para aprender TEI.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Fragmento de prueba codificado manualmente.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <p>Este es un texto mínimo en TEI.</p>
    </body>
  </text>
</TEI>'''

print(tei_minimo)
with open("tei_minimo_leccion3.xml", "w", encoding="utf-8") as f:
    f.write(tei_minimo)

print("Archivo guardado como tei_minimo_leccion3.xml")
tei_estructura_texto = '''<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Erec</title>
        <author>Hartmann von Aue</author>
      </titleStmt>
      <publicationStmt>
        <p>Práctica de estructura textual en TEI.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Ejemplo didáctico para aprender a usar div, p, lg y l.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <div type="introduccion">
        <head>Introducción</head>
        <p>Este bloque representa una sección en prosa.</p>
        <p>Puede contener uno o varios párrafos.</p>
      </div>
      <div type="poem">
        <head>Pasaje en verso</head>
        <lg type="stanza">
          <l n="1">Uns ist in alten maeren</l>
          <l n="2">wunders vil geseit</l>
          <l n="3">von helden lobebaeren</l>
          <l n="4">von grôzer arebeit</l>
        </lg>
      </div>
    </body>
  </text>
</TEI>'''

print(tei_estructura_texto)

with open("tei_estructura_leccion4.xml", "w", encoding="utf-8") as f:
    f.write(tei_estructura_texto)

print("Archivo guardado como tei_estructura_leccion4.xml")

Lección 5: Hacer bien el teiHeader

NotaObjetivo

En esta lección aprenderás a construir correctamente el teiHeader de un documento TEI. La meta es que tus archivos no solo contengan texto, sino también una descripción académica mínima y útil.

1. Qué es el teiHeader

El teiHeader es la parte del documento TEI que contiene los metadatos.

No codifica el contenido textual en sí, sino información sobre el archivo, su preparación, su publicación y su fuente.

Dicho de otro modo:

  • <text> contiene el texto.
  • <teiHeader> describe el texto y el archivo.

2. La pieza central: fileDesc

Dentro del teiHeader, el elemento más importante para empezar es <fileDesc>.

Es la descripción básica del archivo TEI.

En un nivel inicial, debes pensar en fileDesc como una ficha mínima del documento.

3. Los tres bloques que debes dominar

Dentro de <fileDesc> hay tres elementos que debes aprender muy bien:

  • <titleStmt>
  • <publicationStmt>
  • <sourceDesc>

<titleStmt>

Aquí indicas el título de la obra y las personas responsables.

Puede incluir, por ejemplo:

  • <title>
  • <author>
  • <editor>
  • <respStmt>

Ejemplo:

<titleStmt>
  <title>Iwein</title>
  <author>Hartmann von Aue</author>
  <respStmt>
    <resp>Codificación TEI</resp>
    <name>Tu nombre</name>
  </respStmt>
</titleStmt>

<publicationStmt>

Aquí describes la publicación o difusión del archivo digital.

Para una práctica inicial, un párrafo simple basta.

Ejemplo:

<publicationStmt>
  <p>Archivo TEI creado con fines docentes y de aprendizaje.</p>
</publicationStmt>

Más adelante podrás añadir editor institucional, licencia, fecha o disponibilidad.

<sourceDesc>

Aquí explicas de dónde procede el texto codificado.

Este punto es muy importante en filología y edición crítica, porque documenta la fuente.

Ejemplo simple:

<sourceDesc>
  <p>Transcripción de práctica basada en una edición moderna del texto.</p>
</sourceDesc>

4. Plantilla mínima funcional

<teiHeader>
  <fileDesc>
    <titleStmt>
      <title>Erec</title>
      <author>Hartmann von Aue</author>
      <respStmt>
        <resp>Codificación TEI</resp>
        <name>Tu nombre</name>
      </respStmt>
    </titleStmt>
    <publicationStmt>
      <p>Documento de práctica para aprender TEI.</p>
    </publicationStmt>
    <sourceDesc>
      <p>Fragmento de trabajo basado en una fuente textual identificada por el editor.</p>
    </sourceDesc>
  </fileDesc>
</teiHeader>

5. Qué debes escribir en cada parte

Piensa en estas preguntas:

Para titleStmt

  • ¿Cuál es el título de la obra?
  • ¿Quién es el autor?
  • ¿Quién ha hecho la codificación o edición?

Para publicationStmt

  • ¿Qué es este archivo?
  • ¿Se ha hecho para docencia, investigación o publicación?
  • ¿Hay alguna nota de distribución o uso?

Para sourceDesc

  • ¿De dónde sale el texto?
  • ¿Es una edición impresa?
  • ¿Es una transcripción propia?
  • ¿Es un manuscrito, una edición digital o una adaptación de trabajo?
AdvertenciaError frecuente

Un error muy común es escribir un teiHeader demasiado pobre, por ejemplo:

<teiHeader>
  <fileDesc>
    <titleStmt>
      <title>Texto</title>
    </titleStmt>
  </fileDesc>
</teiHeader>

Eso no basta, porque deja fuera información clave sobre publicación y fuente.

7. Versión mejorada

<teiHeader>
  <fileDesc>
    <titleStmt>
      <title>Texto</title>
      <author>Autor desconocido</author>
      <respStmt>
        <resp>Codificación TEI</resp>
        <name>Nombre del editor</name>
      </respStmt>
    </titleStmt>
    <publicationStmt>
      <p>Archivo creado para práctica de edición digital.</p>
    </publicationStmt>
    <sourceDesc>
      <p>Texto preparado a partir de una transcripción de trabajo.</p>
    </sourceDesc>
  </fileDesc>
</teiHeader>
ImportanteQué debes retener

Quédate con esta lógica:

  1. titleStmt dice qué es y quién interviene.
  2. publicationStmt dice cómo circula el archivo.
  3. sourceDesc dice de dónde sale el texto.
PrecauciónTarea final
  • Crea un teiHeader propio para una obra medieval.
  • Añade tu nombre en un respStmt.
  • Redacta un publicationStmt breve pero claro.
  • Escribe un sourceDesc filológicamente útil y no genérico.

Lección 6: Validación y control de calidad

NotaObjetivo

En esta lección aprenderás a comprobar si tu archivo XML-TEI está correcto desde dos puntos de vista:

  1. si está bien formado;
  2. si además es válido.

La meta es que no solo escribas TEI, sino que sepas detectar y corregir errores.

1. Dos niveles de corrección

Cuando trabajas con XML y TEI, hay dos preguntas distintas:

  • ¿Está bien formado?
  • ¿Es válido?

No significan lo mismo.

2. Qué significa “bien formado”

Un documento bien formado respeta las reglas básicas de XML.

Por ejemplo:

  • tiene una sola raíz;
  • cierra todas las etiquetas;
  • respeta mayúsculas y minúsculas;
  • anida bien los elementos;
  • usa atributos correctamente.

Si falla aquí, el archivo está roto a nivel de sintaxis.

3. Qué significa “válido”

Un documento válido es un documento bien formado que además cumple las reglas de un esquema.

Ese esquema define qué elementos pueden aparecer, en qué orden, con qué atributos y en qué contextos.

En TEI, esto significa que no basta con escribir XML correcto: también debes ajustarte al modelo TEI o al esquema del proyecto.

4. Esquemas y validación

Para validar un XML se usa un esquema.

En la práctica puedes encontrar varios tipos:

  • DTD
  • XML Schema
  • Relax NG
  • Schematron

No necesitas dominar ahora sus diferencias técnicas.

Lo importante en esta fase es entender que un esquema actúa como una gramática del documento.

5. Lo que hace Oxygen

En Oxygen puedes hacer dos comprobaciones distintas:

  • comprobar la buena formación del XML;
  • validar el archivo contra su esquema.

Ambas son necesarias.

Un archivo puede estar bien formado y aun así no ser válido como TEI.

6. Ejemplo conceptual

Este ejemplo puede estar bien formado:

<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Iwein</title>
      </titleStmt>
      <publicationStmt>
        <p>Práctica</p>
      </publicationStmt>
      <sourceDesc>
        <p>Fuente de prueba</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <banana>Texto</banana>
    </body>
  </text>
</TEI>

Como XML, el documento puede estar bien cerrado.

Pero como TEI, el elemento <banana> no tiene sentido en ese contexto y el esquema lo rechazaría.

7. Estrategia de trabajo

Trabaja así:

  1. escribe un pequeño bloque;
  2. comprueba si está bien formado;
  3. valida contra el esquema;
  4. corrige el error antes de seguir;
  5. continúa solo cuando el documento vuelva a estar limpio.

Esto ahorra muchísimo tiempo.

8. Errores típicos que debes buscar

A. Errores de buena formación

  • etiquetas sin cerrar;
  • comillas ausentes en atributos;
  • anidación incorrecta;
  • dos raíces;
  • uso incorrecto de & o <.

B. Errores de validez TEI

  • elementos no permitidos;
  • elementos permitidos en lugar incorrecto;
  • falta de componentes obligatorios;
  • atributos no admitidos;
  • orden incorrecto de subelementos.

9. Buenas prácticas

  • valida a menudo;
  • no acumules errores;
  • corrige primero los errores estructurales;
  • luego revisa los errores de esquema;
  • guarda versiones del archivo conforme avanzas.
ImportanteQué debes retener

Quédate con esta fórmula:

  • bien formado = sintaxis XML correcta;
  • válido = sintaxis correcta + conformidad con un esquema.
TipMini ejercicio

Decide qué pasa en cada caso:

Caso A.

<p>Texto sin cierre

Caso B.

<l n="1">Verso</l>

Caso C.

<text>
  <body>
    <objetoInventado>Prueba</objetoInventado>
  </body>
</text>
  • Caso A: no está bien formado.
  • Caso B: puede estar bien formado.
  • Caso C: puede estar bien formado como XML, pero probablemente no será válido en TEI.
PrecauciónTarea final
  • Abre uno de tus archivos TEI.
  • Revisa primero si está bien formado.
  • Después valídalo.
  • Haz una lista de tres errores posibles: uno de sintaxis XML y dos de validez TEI.

Lección 7: Marcado filológico básico en TEI

NotaObjetivo

En esta lección aprenderás a codificar algunos fenómenos filológicos fundamentales en TEI. La meta es que puedas representar no solo el texto, sino también decisiones editoriales e incertidumbres de lectura.

1. Por qué esta lección es importante

Hasta ahora has aprendido a crear la estructura general de un documento TEI.

Pero una edición filológica necesita algo más: debe poder reflejar problemas del texto.

Por ejemplo:

  • abreviaturas;
  • expansiones;
  • errores aparentes;
  • correcciones;
  • formas originales y regularizadas;
  • lagunas;
  • lecturas dudosas;
  • texto reconstruido.

Aquí es donde TEI se vuelve verdaderamente útil para edición académica.

2. El principio de choice

El elemento <choice> sirve para agrupar alternativas de codificación de una misma secuencia textual.

La idea es esta:

  • una forma transmite lo que aparece en el testimonio;
  • otra forma transmite la intervención editorial o la interpretación.

Por eso choice es muy útil en edición.

3. Abreviatura y expansión

Para marcar una abreviatura y su desarrollo se usan:

  • <abbr> para la forma abreviada;
  • <expan> para la forma expandida.

Ejemplo:

<choice>
  <abbr>dn̄</abbr>
  <expan>dominus</expan>
</choice>

Esto permite conservar tanto la forma abreviada del testimonio como su expansión editorial.

4. Error aparente y corrección

Para indicar que en la fuente aparece una forma aparentemente errónea, pero que el editor ofrece una corrección, se usan:

  • <sic> para lo transmitido;
  • <corr> para la corrección.

Ejemplo:

<choice>
  <sic>kunic</sic>
  <corr>künic</corr>
</choice>

La lógica es muy importante:

  • sic = “así está”;
  • corr = “así lo corrijo”.

5. Forma original y forma regularizada

Si no quieres hablar de error, sino de normalización o regularización, puedes usar:

  • <orig> para la forma original;
  • <reg> para la forma regularizada.

Ejemplo:

<choice>
  <orig>vn̄de</orig>
  <reg>unde</reg>
</choice>

Esto es especialmente útil cuando no corriges un error, sino que ofreces una forma normalizada para facilitar búsqueda o lectura.

6. Lecturas dudosas

Cuando no puedes leer una palabra con total seguridad, puedes usar <unclear>.

Ejemplo:

<unclear>ritter</unclear>

Eso indica que la lectura es incierta.

No quiere decir necesariamente que falte el texto, sino que su lectura no es completamente segura.

7. Lagunas

Cuando el texto falta o no puede transcribirse, se usa <gap>.

Ejemplo:

<gap reason="illegible"/>

o bien:

<gap reason="lost" quantity="3" unit="words"/>

Esto no reconstruye el texto: solo indica que hay una ausencia o una omisión.

8. Texto suplido

Si el editor reconstruye un pasaje perdido o ilegible, normalmente se usa <supplied>.

Ejemplo:

<supplied reason="lost">ritter</supplied>

La idea es clara:

  • gap señala la falta;
  • supplied propone una restitución editorial.

9. Cómo decidir entre varios pares

Usa esta guía rápida:

  • abreviatura desarrollada: abbr + expan
  • error corregido: sic + corr
  • forma original normalizada: orig + reg
  • lectura insegura: unclear
  • texto ausente: gap
  • texto reconstruido: supplied

10. Ejemplos integrados

Abreviatura expandida

<l n="12">er sprach ze <choice><abbr>gōt</abbr><expan>gott</expan></choice></l>

Error y corrección

<l n="13">des was der <choice><sic>kunic</sic><corr>künic</corr></choice> vrô</l>

Original y regularización

<l n="14">sîn <choice><orig>vn̄de</orig><reg>unde</reg></choice> sîn muot</l>

Lectura dudosa

<l n="15">dô quam ein <unclear>ritter</unclear> geriten</l>

Laguna

<l n="16">dô sprach <gap reason="illegible"/></l>

Restitución editorial

<l n="17">dô sprach <supplied reason="lost">der ritter</supplied></l>
AdvertenciaError frecuente

Un error común es mezclar categorías distintas.

Por ejemplo:

  • usar corr cuando en realidad solo regularizas;
  • usar reg cuando en realidad corriges un error;
  • usar supplied cuando no estás reconstruyendo nada;
  • usar unclear cuando en realidad el texto está ausente y deberías marcar un gap.
ImportanteQué debes retener

Quédate con esta lógica general:

  1. TEI permite representar el texto y la intervención editorial al mismo tiempo.
  2. choice sirve para alternativas de codificación.
  3. sic/corr expresa corrección.
  4. orig/reg expresa regularización.
  5. abbr/expan expresa desarrollo de abreviaturas.
  6. unclear, gap y supplied expresan grados distintos de incertidumbre o pérdida.
PrecauciónTarea final
  • Escribe un ejemplo con abbr y expan.
  • Escribe otro con sic y corr.
  • Escribe otro con orig y reg.
  • Añade un verso con unclear.
  • Añade otro con gap.
  • Añade otro con supplied.

Código de práctica (Python)

Estas celdas son opcionales: no sustituyen a Oxygen, pero permiten manipular los mismos ejemplos como texto dentro de un cuaderno Jupyter, Colab o un chunk de Quarto/RStudio.

tei_filologico = '''<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Práctica filológica TEI</title>
        <author>Texto medieval de ejemplo</author>
      </titleStmt>
      <publicationStmt>
        <p>Documento de práctica para aprender marcado filológico básico.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Fragmento de prueba para abreviaturas, correcciones y lagunas.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <lg type="verse">
        <l n="1">er sprach ze <choice><abbr>gōt</abbr><expan>gott</expan></choice></l>
        <l n="2">des was der <choice><sic>kunic</sic><corr>künic</corr></choice> vrô</l>
        <l n="3">sîn <choice><orig>vn̄de</orig><reg>unde</reg></choice> muot was hôch</l>
        <l n="4">dô quam ein <unclear>ritter</unclear> geriten</l>
        <l n="5">dô sprach <gap reason="illegible"/></l>
        <l n="6">dô sprach <supplied reason="lost">der ritter</supplied></l>
      </lg>
    </body>
  </text>
</TEI>'''

print(tei_filologico)
with open("tei_filologico_leccion7.xml", "w", encoding="utf-8") as f:
    f.write(tei_filologico)

print("Archivo guardado como tei_filologico_leccion7.xml")
plantilla_choice = {
    "abreviatura": "<choice><abbr>dn̄</abbr><expan>dominus</expan></choice>",
    "correccion": "<choice><sic>kunic</sic><corr>künic</corr></choice>",
    "regularizacion": "<choice><orig>vn̄de</orig><reg>unde</reg></choice>",
    "lectura_dudosa": "<unclear>ritter</unclear>",
    "laguna": "<gap reason=\"illegible\"/>",
    "restitucion": "<supplied reason=\"lost\">ritter</supplied>"
}

for etiqueta, ejemplo in plantilla_choice.items():
    print(f"{etiqueta}: {ejemplo}")

Lección 8: Aparato crítico básico en TEI

NotaObjetivo

En esta lección aprenderás a representar variantes textuales básicas en TEI. La meta es que puedas codificar un aparato crítico elemental con lema, lecturas y testigos.

1. Qué es un aparato crítico en TEI

Una edición crítica no solo presenta un texto, sino también información sobre sus variantes.

TEI permite codificar esas variantes de forma estructurada.

La unidad básica del aparato crítico es <app>.

Dentro de ella suelen aparecer:

  • <lem> para la lectura elegida como lema o base;
  • <rdg> para las lecturas variantes.

2. La lógica de <app>

Piensa en <app> como una cápsula que reúne todas las posibilidades de un mismo lugar textual.

Es decir:

  • en un punto del texto hay una variación;
  • el aparato recoge las distintas lecturas posibles;
  • cada lectura puede vincularse a uno o varios testigos.

3. Elementos fundamentales

<app>

Contiene una entrada del aparato crítico.

<lem>

Contiene la lectura que el editor adopta como lema, o la lectura del testimonio base si se trabaja así.

<rdg>

Contiene una lectura variante.

4. El atributo @wit

Las lecturas se vinculan a testigos mediante @wit.

Ese atributo apunta normalmente a identificadores definidos en una lista de testigos.

Ejemplo:

<rdg wit="#A">künic</rdg>

Aquí la lectura künic pertenece al testigo A.

5. Lista de testigos

Para que el aparato sea interpretable, conviene declarar los testigos en el documento.

Esto se hace con una lista como esta:

<listWit>
  <witness xml:id="A">Manuscrito A</witness>
  <witness xml:id="B">Manuscrito B</witness>
  <witness xml:id="C">Manuscrito C</witness>
</listWit>

Después, en @wit, se remite a esos identificadores:

  • #A
  • #B
  • #C

6. Ejemplo mínimo

<app>
  <lem wit="#A">künic</lem>
  <rdg wit="#B">kunic</rdg>
  <rdg wit="#C">küning</rdg>
</app>

Esto quiere decir:

  • el lema adoptado es künic, atestiguado en A;
  • B tiene kunic;
  • C tiene küning.

7. Inserción dentro del texto

El aparato no está aislado del texto, sino incrustado en él.

Ejemplo:

<l n="12">des was der
  <app>
    <lem wit="#A">künic</lem>
    <rdg wit="#B">kunic</rdg>
    <rdg wit="#C">küning</rdg>
  </app>
  vrô
</l>

Así, el aparato se sitúa exactamente en el lugar del texto donde aparece la variación.

8. Qué representa el lema

Debes tener clara una cosa: <lem> no significa siempre “lectura verdadera”.

Puede representar:

  • la lectura elegida por el editor;
  • la lectura del testimonio base;
  • la lectura que se muestra en el texto principal.

Lo importante es ser consistente y documentarlo en la edición.

9. Un ejemplo con varios testigos por lectura

Si varios testigos comparten la misma lectura, puedes agruparlos:

<app>
  <lem wit="#A #B">ritter</lem>
  <rdg wit="#C">reiter</rdg>
</app>

Aquí A y B transmiten la misma forma.

AdvertenciaError frecuente

Un error frecuente es no declarar previamente los testigos y usar @wit como si fuera una etiqueta libre.

Por ejemplo:

<rdg wit="manuscrito bueno">künic</rdg>

Eso no es una buena práctica.

Es mejor definir antes los testigos con identificadores estables.

AdvertenciaOtro error frecuente

Otro error muy común es mezclar aparato crítico y corrección editorial sin distinguir niveles.

Por ejemplo:

  • sic/corr sirve para error y corrección editorial en un testimonio;
  • app/lem/rdg sirve para variantes entre testigos o versiones.

No conviene usarlos como si fueran exactamente lo mismo.

ImportanteQué debes retener

Quédate con esta estructura:

  1. <app> = unidad de variación.
  2. <lem> = lectura base o adoptada.
  3. <rdg> = lectura variante.
  4. @wit = vinculación con testigos.
  5. <listWit> = definición de los testigos.
PrecauciónTarea final
  • Crea una lista de tres testigos: A, B y C.
  • Codifica una variante simple con un lema y dos lecturas.
  • Inserta esa variante dentro de un verso <l>.
  • Crea un segundo ejemplo en el que dos testigos compartan la misma lectura.

Código de práctica (Python)

Estas celdas son opcionales: no sustituyen a Oxygen, pero permiten manipular los mismos ejemplos como texto dentro de un cuaderno Jupyter, Colab o un chunk de Quarto/RStudio.

tei_aparato = '''<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Práctica de aparato crítico</title>
        <author>Texto medieval de ejemplo</author>
      </titleStmt>
      <publicationStmt>
        <p>Documento de práctica para aprender aparato crítico básico en TEI.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Fragmento didáctico con variantes entre tres testigos.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <listWit>
        <witness xml:id="A">Manuscrito A</witness>
        <witness xml:id="B">Manuscrito B</witness>
        <witness xml:id="C">Manuscrito C</witness>
      </listWit>
      <lg type="verse">
        <l n="12">des was der
          <app>
            <lem wit="#A">künic</lem>
            <rdg wit="#B">kunic</rdg>
            <rdg wit="#C">küning</rdg>
          </app>
          vrô
        </l>
        <l n="13">dô quam ein
          <app>
            <lem wit="#A #B">ritter</lem>
            <rdg wit="#C">reiter</rdg>
          </app>
          geriten
        </l>
      </lg>
    </body>
  </text>
</TEI>'''

print(tei_aparato)
with open("tei_aparato_leccion8.xml", "w", encoding="utf-8") as f:
    f.write(tei_aparato)

print("Archivo guardado como tei_aparato_leccion8.xml")
variantes = {
    "variante_1": {
        "lem": "künic",
        "rdg_B": "kunic",
        "rdg_C": "küning"
    },
    "variante_2": {
        "lem_AB": "ritter",
        "rdg_C": "reiter"
    }
}

for nombre, datos in variantes.items():
    print(f"--- {nombre} ---")
    for clave, valor in datos.items():
        print(f"{clave}: {valor}")

Lección 9: Consultar TEI con XPath

NotaObjetivo

En esta lección aprenderás a hacer búsquedas estructuradas dentro de un documento XML-TEI usando XPath. La meta es que no solo codifiques textos, sino que también sepas interrogarlos.

1. Qué es XPath

XPath es un lenguaje de consulta para XML.

Sirve para seleccionar nodos dentro de un documento:

  • elementos;
  • atributos;
  • texto;
  • grupos de nodos.

Piensa en XPath como una forma de decir:

  • “dame todos los versos”;
  • “dame todos los párrafos”;
  • “dame todos los elementos con atributo n”;
  • “dame todos los l dentro de un lg”.

2. Idea fundamental

XPath trata el XML como un árbol de nodos.

Por eso puedes recorrerlo con rutas.

Ejemplo simple:

//l

Esto significa:

“selecciona todos los elementos <l> del documento”.

3. Operadores básicos

/

Selecciona desde la raíz o marca un paso directo.

Ejemplo:

/TEI/text

//

Busca en cualquier parte del documento desde el punto actual.

Ejemplo:

//p

Esto busca todos los párrafos, estén donde estén.

@

Selecciona atributos.

Ejemplo:

//@n

Esto selecciona todos los atributos n.

.

Nodo actual.

..

Nodo padre.

4. Primeras consultas útiles

Todos los versos

//l

Todos los grupos de versos

//lg

Todos los párrafos

//p

Todas las divisiones

//div

Todos los encabezados

//head

5. Consultas con atributos

Puedes buscar elementos por atributo.

Todos los versos que tengan atributo n

//l[@n]

El verso cuyo número es 12

//l[@n='12']

Todas las divisiones de tipo poema

//div[@type='poem']

Todos los gap con razón illegible

//gap[@reason='illegible']

6. Consultas por posición

XPath permite seleccionar por posición.

El primer verso

//l[1]

El último verso

//l[last()]

El tercer párrafo

//p[3]

Recuerda: en XPath la numeración empieza en 1, no en 0.

7. Consultas jerárquicas

Puedes combinar niveles estructurales.

Todos los versos dentro de grupos de versos

//lg/l

Todos los párrafos dentro del cuerpo

//body//p

Todos los encabezados de divisiones

//div/head

Todas las lecturas variantes del aparato crítico

//app/rdg

8. Consultas muy útiles para TEI

Todas las abreviaturas

//abbr

Todas las expansiones

//expan

Todas las correcciones

//corr

Todas las formas originales

//orig

Todas las regularizaciones

//reg

Todas las lagunas

//gap

Todos los lugares con lectura dudosa

//unclear

9. Consultas con condiciones

Puedes usar filtros entre corchetes.

Todos los rdg del testigo B

//rdg[@wit='#B']

Todos los lem que pertenecen al testigo A

//lem[@wit='#A']

Todos los elementos que tienen atributo xml:id

//*[@xml:id]

Todos los elementos que tienen cualquier atributo type

//*[@type]

10. Seleccionar texto o atributos

Todos los valores del atributo n

//@n

Todos los valores del atributo wit

//@wit

El texto de todos los versos

//l/text()

Nota importante: text() devuelve nodos de texto. En documentos con marcado interno, el resultado puede fragmentarse.

11. XPath en Oxygen

Oxygen tiene una herramienta específica para ejecutar consultas XPath sobre el documento abierto.

Eso te permite:

  • probar expresiones;
  • comprobar si tu codificación está donde crees;
  • localizar elementos problemáticos;
  • revisar patrones estructurales del archivo.

XPath es útil no solo para análisis, sino también para control de calidad.

AdvertenciaError frecuente

Un error típico es confundir:

/div/l

con

//div//l

No significan lo mismo.

  • /div/l busca una ruta muy concreta desde la raíz.
  • //div//l busca cualquier l descendiente de cualquier div en cualquier parte del documento.

13. Otra dificultad habitual

En TEI, muchas veces el documento usa namespace.

Cuando trabajas con ciertas herramientas, tendrás que declarar el namespace TEI para que XPath funcione correctamente.

En una fase inicial, lo importante es entender la lógica estructural de la consulta, aunque más adelante tendrás que aprender a manejar namespaces explícitamente.

ImportanteQué debes retener

Quédate con estas expresiones clave:

  • //l = todos los versos
  • //p = todos los párrafos
  • //div[@type='poem'] = divisiones de tipo poema
  • //l[@n='12'] = verso número 12
  • //app/rdg = variantes del aparato
  • //*[@type] = todos los elementos con atributo type
PrecauciónTarea final
  • Busca todos los versos de tu archivo.
  • Busca todos los gap.
  • Busca todas las abreviaturas.
  • Busca todos los elementos con atributo n.
  • Busca todas las variantes del testigo B.
  • Prueba una consulta para encontrar un verso concreto por número.

Código de práctica (Python)

Estas celdas son opcionales: no sustituyen a Oxygen, pero permiten manipular los mismos ejemplos como texto dentro de un cuaderno Jupyter, Colab o un chunk de Quarto/RStudio.

pip install lxml
from lxml import etree
tei_xpath = '''<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Práctica XPath sobre TEI</title>
      </titleStmt>
      <publicationStmt>
        <p>Documento didáctico.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Fuente de prueba.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <div type="poem">
        <head>Poema de prueba</head>
        <lg type="stanza">
          <l n="1">Uns ist in alten maeren</l>
          <l n="2">dô quam ein <unclear>ritter</unclear></l>
          <l n="3">dô sprach <gap reason="illegible"/></l>
          <l n="4">
            <app>
              <lem wit="#A">künic</lem>
              <rdg wit="#B">kunic</rdg>
            </app>
          </l>
        </lg>
      </div>
    </body>
  </text>
</TEI>'''

root = etree.fromstring(tei_xpath.encode("utf-8"))
ns = {"tei": "http://www.tei-c.org/ns/1.0"}
print("Documento TEI cargado.")
versos = root.xpath("//tei:l", namespaces=ns)
print("Número de versos:", len(versos))

gaps = root.xpath("//tei:gap", namespaces=ns)
print("Número de gaps:", len(gaps))

lecturas_B = root.xpath("//tei:rdg[@wit='#B']", namespaces=ns)
print("Lecturas del testigo B:", [etree.tostring(x, encoding='unicode') for x in lecturas_B])

numeros_verso = root.xpath("//tei:l/@n", namespaces=ns)
print("Atributos n de los versos:", numeros_verso)

Lección 10: Transformación y extracción de TEI

NotaObjetivo

En esta lección aprenderás para qué sirve transformar un documento TEI y cómo empezar a hacerlo. La meta es que entiendas cómo pasar de un XML codificado a una salida útil, como HTML o texto plano.

1. Por qué transformar un TEI

Codificar en TEI no suele ser el final del proceso.

Después de codificar, normalmente quieres hacer alguna de estas cosas:

  • visualizar el texto;
  • publicar una versión legible;
  • extraer texto plano;
  • convertir el XML en HTML;
  • generar otros formatos de trabajo.

Aquí entra en juego la transformación.

2. Qué es XSLT

XSLT es un lenguaje de transformación para documentos XML.

Su función es leer un XML de entrada y producir otro resultado de salida.

Ese resultado puede ser:

  • otro XML;
  • HTML;
  • texto plano;
  • otros formatos serializados.

Piensa en XSLT como un sistema de reglas que dice:

  • “cuando encuentres este elemento XML, conviértelo en esta otra cosa”.

3. Idea fundamental

XSLT trabaja con plantillas.

Cada plantilla define qué hacer cuando el procesador encuentra un determinado nodo.

Por ejemplo:

  • si encuentra <title>, lo convierte en un encabezado HTML;
  • si encuentra <p>, lo convierte en un párrafo HTML;
  • si encuentra <l>, puede convertirlo en una línea con salto.

4. Un ejemplo mínimo: TEI a HTML

Supongamos este XML:

<text>
  <body>
    <p>Este es un párrafo.</p>
  </body>
</text>

Una transformación XSLT puede convertirlo en:

<p>Este es un párrafo.</p>

5. Estructura básica de una hoja XSLT

Una hoja XSLT mínima tiene esta forma:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

Aquí:

  • xsl:stylesheet declara la hoja;
  • xsl:template match="/" define qué hacer con la raíz;
  • xsl:apply-templates dice que se sigan procesando los nodos del documento.

6. Añadir reglas concretas

Puedes añadir una regla para los párrafos:

<xsl:template match="p">
  <p><xsl:apply-templates/></p>
</xsl:template>

Y otra para los títulos:

<xsl:template match="title">
  <h1><xsl:apply-templates/></h1>
</xsl:template>

La idea es simple:

  • XML de entrada: describe estructura;
  • XSLT: interpreta esa estructura;
  • HTML de salida: la presenta visualmente.

7. Aplicado a TEI

En un documento TEI, XSLT puede usarse para transformar, por ejemplo:

  • <head> en <h1> o <h2>;
  • <p> en <p>;
  • <l> en líneas con <br/> o en bloques HTML;
  • <lg> en un contenedor de estrofa;
  • <choice> en distintas visualizaciones según quieras mostrar original, regularización o expansión.

Esto es importante: la transformación depende de lo que quieras mostrar.

8. Extraer texto plano

A veces no quieres HTML, sino simplemente sacar el texto del TEI.

Esto puede hacerse con XSLT o con otras herramientas.

Por ejemplo, una extracción muy simple de texto plano consiste en ignorar las etiquetas y recuperar solo el contenido textual del <body>.

Esto es útil para:

  • estilometría;
  • concordancias;
  • análisis léxico;
  • exportación a corpus de trabajo.

9. Transformación en Oxygen

Oxygen permite configurar un escenario de transformación XSLT.

La lógica general es esta:

  1. abrir el XML;
  2. abrir o crear la hoja XSLT;
  3. configurar el escenario de transformación;
  4. ejecutar la transformación;
  5. revisar el archivo de salida.

Es una manera muy práctica de repetir procesos sin rehacer todo cada vez.

10. Una diferencia importante

No confundas:

  • consultar con XPath;
  • transformar con XSLT.

XPath sirve para localizar nodos. XSLT usa XPath internamente, pero su objetivo es producir una salida nueva.

11. Ejemplo mental útil

Piensa así:

  • XPath pregunta: “¿dónde están los versos?”
  • XSLT dice: “cuando encuentres un verso, conviértelo en este formato de salida”.
ImportanteQué debes retener

Quédate con estas ideas:

  1. TEI codifica estructura y significado.
  2. XSLT transforma esa estructura en otra salida.
  3. Puedes transformar TEI a HTML, XML o texto plano.
  4. Oxygen permite automatizar estas transformaciones.
  5. XPath y XSLT están relacionados, pero no son lo mismo.
PrecauciónTarea final
  • Imagina cómo transformarías <head>, <p> y <l> a HTML.
  • Piensa qué salida querrías para un choice: original, regularizada o ambas.
  • Decide si para tu trabajo te interesa más transformar a HTML o extraer texto plano.

Código de práctica (Python)

Estas celdas son opcionales: no sustituyen a Oxygen, pero permiten manipular los mismos ejemplos como texto dentro de un cuaderno Jupyter, Colab o un chunk de Quarto/RStudio.

from lxml import etree
tei_transformacion = '''<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Práctica de transformación TEI</title>
      </titleStmt>
      <publicationStmt>
        <p>Documento didáctico.</p>
      </publicationStmt>
      <sourceDesc>
        <p>Fuente de prueba.</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <div type="intro">
        <head>Introducción</head>
        <p>Este es el primer párrafo.</p>
      </div>
      <div type="poem">
        <head>Poema</head>
        <lg type="stanza">
          <l n="1">Uns ist in alten maeren</l>
          <l n="2">wunders vil geseit</l>
        </lg>
      </div>
    </body>
  </text>
</TEI>'''

root = etree.fromstring(tei_transformacion.encode("utf-8"))
ns = {"tei": "http://www.tei-c.org/ns/1.0"}
print("TEI cargado.")
texto_plano = " ".join(root.xpath("//tei:body//text()", namespaces=ns))
print(texto_plano)
html_partes = []

for head in root.xpath("//tei:head", namespaces=ns):
    html_partes.append(f"<h2>{head.text}</h2>")

for p in root.xpath("//tei:p", namespaces=ns):
    html_partes.append(f"<p>{''.join(p.itertext())}</p>")

for lg in root.xpath("//tei:lg", namespaces=ns):
    versos = []
    for l in lg.xpath("./tei:l", namespaces=ns):
        versos.append(f"<div class='verso'>{''.join(l.itertext())}</div>")
    html_partes.append("<div class='estrofa'>" + "".join(versos) + "</div>")

html_salida = "<html><body>" + "".join(html_partes) + "</body></html>"
print(html_salida)

Lección 11: Flujo de trabajo y publicación básica con TEI

NotaObjetivo

En esta lección aprenderás a organizar un flujo de trabajo razonable para editar, validar, guardar y publicar textos TEI. La meta es que no trabajes con archivos sueltos, sino con un proceso estable y reutilizable.

1. Por qué hace falta un flujo de trabajo

En un proyecto TEI no basta con codificar bien un archivo. También necesitas saber dónde lo guardas, cómo lo validas, cómo controlas cambios y cómo produces una salida publicable.

2. Espacio de trabajo

Una práctica habitual es trabajar dentro de una carpeta de proyecto, abierta en el editor XML como espacio de trabajo. En Oxygen, ese flujo puede organizarse añadiendo una carpeta de proyecto y creando un archivo de proyecto propio.

3. Crear un archivo TEI desde plantilla

Oxygen permite crear un archivo nuevo a partir de una plantilla TEI dentro del framework correspondiente. En el flujo descrito para Oxygen, se recomienda crear el archivo desde Framework > TEI > All [TEI], lo que facilita partir de una estructura compatible desde el inicio.

4. Validar desde el principio

Cada vez que añades o modificas una parte importante del XML, conviene validar. Oxygen distingue entre comprobar la buena formación del XML y validar contra un esquema, y soporta validación con XML Schema, DTD, Schematron y Relax NG.

5. Guardar y versionar

Guardar no es suficiente si el archivo evoluciona durante semanas o meses. Por eso muchos flujos TEI combinan edición XML con Git y GitHub, de modo que cada cambio importante quede registrado en commits con mensaje descriptivo.

6. Rutina diaria recomendable

Una rutina de trabajo muy razonable es esta:

  1. hacer Pull antes de empezar;
  2. editar o crear archivos;
  3. validar;
  4. revisar cambios;
  5. hacer commit con un mensaje claro;
  6. hacer Push al repositorio remoto.

Esta secuencia reduce conflictos y deja trazabilidad del trabajo editorial.

7. Actualización del entorno TEI

Si trabajas regularmente con Oxygen, conviene mantener actualizado el framework TEI. El plugin TEI para Oxygen existe precisamente para mantener el entorno alineado con nuevas versiones de las Guidelines y de los estilos XSL asociados.

8. De la edición a la publicación

Una vez validado el TEI, puedes producir distintas salidas: HTML, impresión o sitios web de edición. Herramientas como TEI Publisher están pensadas para simplificar el flujo editorial y ofrecer publicación web sobre documentos TEI.

9. Publicación estática

Si no necesitas una plataforma dinámica completa, también existen enfoques de publicación estática. TEI Publisher dispone incluso de un generador estático capaz de pre-generar una versión estática de un sitio basado en TEI.

ImportanteQué debes retener

Quédate con esta cadena de trabajo:

  1. proyecto;
  2. plantilla TEI;
  3. edición;
  4. validación;
  5. control de versiones;
  6. transformación;
  7. publicación.
PrecauciónTarea final
  • Crea una carpeta de proyecto para tus ejercicios TEI.
  • Abre esa carpeta en Oxygen.
  • Crea un archivo nuevo desde plantilla TEI.
  • Valídalo.
  • Guarda el archivo con un nombre claro.
  • Imagina qué mensaje de commit escribirías si lo subieras a GitHub.

Lección 12: TEI Publisher y MENOTA

NotaObjetivo

En esta lección conocerás dos cosas complementarias:

  1. una herramienta para publicar ediciones TEI en la web;
  2. un modelo real de archivo y edición medieval digital basado en TEI.

La meta es que veas cómo tus archivos XML-TEI pueden insertarse en un ecosistema de publicación y reutilización académica.

Parte A: TEI Publisher

1. Qué es TEI Publisher

TEI Publisher es una plataforma basada en eXist-db pensada para publicar archivos TEI XML y otros tipos de XML. Se presenta como una herramienta relativamente fácil de usar para convertir XML en una aplicación o edición web publicable.

2. Para qué sirve

TEI Publisher permite publicar distintos tipos de materiales, desde presentaciones básicas de textos digitales hasta ediciones académicas más complejas. También admite distintas formas de presentación como transcripción, traducción, facsímiles y anotaciones.

3. Qué aporta a un proyecto TEI

Su valor principal es que reduce la distancia entre codificación y publicación. En lugar de limitarte a guardar XML, puedes convertir tu corpus o edición en una interfaz navegable en la web.

4. Editor de anotación

TEI Publisher incluye un editor web de anotación que ayuda a ampliar una transcripción base con anotación semántica. También existen configuraciones de anotación que pueden usarse directamente o servir como modelo para adaptaciones de proyecto.

5. Salidas y modos

TEI Publisher trabaja con varios modos de salida. Su ecosistema soporta al menos salida web y otras opciones vinculadas a impresión o generación derivada, y además existe un generador estático para pre-generar una versión estática de un sitio.

6. Por qué puede interesarte

Si tienes ya TEI bien estructurado, TEI Publisher te permite pasar de archivo codificado a edición visible sin tener que construir toda la capa web desde cero. En un curso de TEI, esto representa el puente entre edición y publicación.

Parte B: MENOTA

7. Qué es MENOTA

MENOTA significa Medieval Nordic Text Archive. Es una red de archivos, bibliotecas y departamentos de investigación que trabaja con textos medievales y facsímiles manuscritos.

8. Objetivo de MENOTA

Su objetivo es preservar y publicar textos medievales en formato digital y desarrollar los estándares de codificación necesarios para ello. El archivo incluye textos en lenguas nórdicas y también en latín.

9. Por qué importa metodológicamente

MENOTA es interesante porque muestra cómo TEI puede sostener una infraestructura completa de edición medieval digital. No es solo una colección de archivos XML, sino un modelo de archivo, publicación y reutilización académica.

10. XML descargable y reutilización

Las ediciones digitales alojadas en la plataforma tienen su XML disponible para descarga. Eso convierte a MENOTA en un recurso útil no solo para lectura, sino también para análisis, comparación y reutilización investigadora.

11. MENOTA y las extensiones TEI

MENOTA se basa en TEI, pero además define extensiones propias para problemas frecuentes en textos medievales nórdicos, especialmente la fuerte variación ortográfica y el abundante uso de abreviaturas.

12. Qué puedes aprender de MENOTA aunque no trabajes filología nórdica

Aunque tu objeto de estudio no sea nórdico, MENOTA ofrece un modelo muy valioso para pensar ediciones medievales con facsímiles, niveles de representación textual y XML reutilizable. Su interés está en la arquitectura editorial, no solo en su corpus.

ImportanteQué debes retener

Quédate con esta distinción:

  • TEI Publisher = herramienta para publicar TEI;
  • MENOTA = ejemplo real de archivo y edición medieval digital basada en TEI.
PrecauciónTarea final
  • Piensa si tu futuro proyecto TEI necesitaría solo archivos XML o también una publicación web.
  • Imagina qué partes de tu edición se beneficiarían de una interfaz como TEI Publisher.
  • Piensa qué podrías aprender de MENOTA para una edición medieval no nórdica: facsímiles, variantes, abreviaturas, niveles de texto o descarga del XML.

Consulta rápida: chuleta TEI / XML

Referencia de una página con la estructura mínima, el marcado filológico, el aparato crítico, XPath, la validación y el flujo de trabajo. Pensada para imprimirse o tenerse abierta junto a Oxygen.

ImportanteRegla de oro
  • El XML primero debe estar bien formado; luego el TEI debe ser válido.
  • No confundas el texto transmitido con la intervención editorial.
  • Documenta siempre tus decisiones en el teiHeader.

1. XML básico

  • Una sola raíz.
  • Todas las etiquetas se cierran.
  • La anidación debe ser correcta.
  • Los atributos van entre comillas.
  • Usa entidades para caracteres reservados: &lt;, &amp;.

2. Esqueleto mínimo de un documento TEI

<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>...</titleStmt>
      <publicationStmt>...</publicationStmt>
      <sourceDesc>...</sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>...</body>
  </text>
</TEI>
  • fileDesc es obligatorio.
  • Dentro: titleStmt, publicationStmt, sourceDesc.
  • titleStmt: título, autor, responsables.
  • sourceDesc: de dónde sale el texto.

3. choice exprés

Par Significa
abbr + expan abreviatura y su expansión
sic + corr error aparente y corrección editorial
orig + reg forma original y forma regularizada

choice agrupa siempre alternativas de la misma secuencia textual.

4. Incertidumbre

  • unclear = lectura dudosa.
  • gap = ausencia o ilegibilidad.
  • supplied = restitución editorial.
  • No uses supplied si solo estás constatando una falta: para eso está gap.

5. Aparato crítico

  • app = unidad de variación.
  • lem = lectura base o adoptada.
  • rdg = lectura variante.
  • @wit enlaza con los testigos declarados en listWit/witness.

6. XPath exprés

Consulta Significa
//l todos los versos
//l[@n='12'] el verso número 12
//gap todas las lagunas
//rdg[@wit='#B'] variantes del testigo B
//*[@type] elementos con atributo type

7. No confundas esto

  • Bien formado = sintaxis XML correcta. Válido = además cumple el esquema.
  • XPath = consulta. XSLT = transformación.
  • orig/reg = regularización. sic/corr = corrección editorial.
AdvertenciaErrores que se repiten
  • Mezclar niveles editoriales sin explicarlos.
  • Inventar valores de @wit sin una lista de testigos.
  • Dejar un teiHeader vacío o demasiado pobre.
  • Acumular errores sin validar.
  • Confundir una laguna (gap) con una lectura dudosa (unclear).
  • Tratar TEI como si fuera solo formato visual.

8. Flujo de trabajo ideal

  1. Crear proyecto.
  2. Partir de plantilla TEI (en Oxygen: Framework > TEI > All [TEI]).
  3. Editar por bloques pequeños.
  4. Validar a menudo.
  5. Versionar con Git.
  6. Transformar o publicar al final (XSLT, TEI Publisher).

9. Oxygen, en una lista

  • Comprueba la buena formación (well-formedness).
  • Valida contra el esquema (XML Schema, DTD, Relax NG o Schematron).
  • Usa XPath para revisar la estructura.
  • Usa escenarios XSLT para salidas repetibles.

10. MENOTA, en una frase

Ejemplo real de archivo medieval digital basado en TEI: preservación, publicación, facsímiles, reutilización del XML y atención a problemas editoriales reales.