Interview-Vorbereitung: Register für Brief A041263
Carl Maria von Weber an Gottfried Weber, Dresden, 21. Juli 1817. Arbeitsblatt zum Wiedereinstieg, kein fertiges Ergebnis.
Aufgabenstellung
Für den Brief https://weber-gesamtausgabe.de/A041263 ein HTML-Register der erwähnten Personen, Werke und Orte erstellen und, wo möglich, mit einem Link zum entsprechenden Wikipedia-Artikel versehen. Bei Unklarheiten: nach eigenem Ermessen entscheiden.
Beispiel-Format aus der Aufgabe:
<ul>
<li><a href="https://de.wikipedia.org/wiki/Johann_Gänsbacher">Gänsbacher, Johann</a></li>
<li><a href="https://de.wikipedia.org/wiki/Friedrich_Rochlitz">Rochlitz, Johann Friedrich</a></li>
</ul>
Schritt 1: TEI-XML des Briefes holen
Grundlage für alles Weitere ist die TEI-XML-Quelle des Briefes. Der direkte .xml-Endpunkt und die WeGA-API waren zeitweise durch den Bot-Schutz der Seite (Anubis) blockiert, schlichtes curl kam aber durch:
curl -L https://weber-gesamtausgabe.de/A041263.xml -o A041263.xml
-L ist wichtig: der Server leitet weiter, ohne die Option landet nur die Redirect-Antwort in der Datei statt des XML.
Getroffene Scope-Entscheidungen
Der Brief besteht aus vier <div type="writingSession">: Brieftext, eigenhändiges Notenverzeichnis, Bücherverzeichnis von fremder Hand, Nachschrift von Gottfried Weber. Dazu kommt der teiHeader mit Absender/Empfänger.
- Aufgenommen: Personen, Werke und Orte aus allen vier Schreibsessionen (Brieftext und Nachschrift plus beigelegtes Notenverzeichnis und Bücherverzeichnis). Briefautor und Empfänger ebenfalls, da im Briefkopf genannt.
- Ausgeschlossen: der editorische Apparat, also
tei:note[@type='commentary']. Dort tauchen zusätzliche Personen und Orte auf (z. B. Padua, Klüpfel), die im Brief selbst nicht erwähnt sind. - Unklare Identifikationen: markiert statt geraten (z. B. "Graun [Carl Heinrich?]" ohne
@keyim XML, mit Bleistift-Annotation "Hasse" von fremder Hand).
Welche TEI-Elemente markieren was?
So sind die Entitäten in diesem Brief tatsächlich ausgezeichnet (nachgeprüft am XML):
| Entitätstyp | Elemente / Attribute | Stolpersteine in diesem Brief |
|---|---|---|
| Personen | tei:persName/@keytei:rs[@type='person']/@key |
Ein persName ganz ohne @key (Graun). Absender/Empfänger stehen zusätzlich im Header unter tei:correspAction. |
| Werke | tei:workName/@keytei:rs[@type='work']/@key |
Mehrere workName ohne @key (Tonsezkunst, Musik: Zeitung, Marpurgs Fuge...). Nur über @key zu gehen verliert diese Einträge. |
| Orte | tei:settlement/@key |
tei:placeName kommt nur im Header (Verlagsadresse) vor, nicht im Brieftext. Ein tei:region ohne @key (Rheingegenden). Absende-/Empfangsort im Header unter correspAction. |
Nicht registerrelevant, aber im Text vorhanden: tei:rs[@type='letter'] und tei:rs[@type='diaryDay'] (Verweise auf andere Briefe und Tagebucheinträge).
modules/query.xqm, Funktion query:get-facets (ab Zeile 342), wörtlich zitiert (Zeilen 350, 361, 362):
case 'places' return $collection//tei:settlement[ancestor::tei:text or ancestor::tei:ab]/@key | $collection//tei:term[parent::tei:keywords][starts-with(., 'A13')]
...
case 'persons' return $collection//tei:persName[ancestor::tei:text or ancestor::tei:ab or ancestor::tei:notesStmt]/@key | $collection//tei:rs[@type='person'][ancestor::tei:text or ancestor::tei:ab or ancestor::tei:notesStmt]/@key | $collection//tei:term[parent::tei:keywords][starts-with(., 'A00')]
case 'works' return $collection//tei:workName[ancestor::tei:text or ancestor::tei:ab or ancestor::tei:notesStmt]/@key[string-length(.) = 7] | $collection//tei:rs[@type='work'][ancestor::tei:text or ancestor::tei:ab or ancestor::tei:notesStmt]/@key[string-length(.) = 7] | $collection//tei:term[parent::tei:keywords][starts-with(., 'A02')]
Achtung: das läuft über eine ganze Collection (Facetten für die Suche), nicht über ein einzelnes Dokument. Für die Aufgabe anpassen. Die Idee dahinter ist aber genau die richtige: über ancestor::-Bedingungen den Geltungsbereich eingrenzen. Zu bedenken: ancestor::tei:text allein reicht für diesen Brief nicht, denn die Kommentar-Noten stehen innerhalb von tei:text.
XQuery-Skelett zum Selbst-Vervollständigen
Als Funktion mit dem Dokument als Parameter, nicht auf A041263 festgenagelt. Lücken sind mit (: ??? :) markiert und selbst zu füllen, am besten direkt in eXide gegen das echte Dokument.
xquery version "3.1";
declare namespace tei="http://www.tei-c.org/ns/1.0";
(: Pfad an die eigene eXist-Instanz anpassen :)
let $doc := doc('(: ??? :)/A041263.xml')
return local:persons($doc)
Personen
declare function local:persons($doc as document-node()) as element(ul) {
(: TODO: tei:persName/@key und tei:rs[@type='person']/@key selektieren,
beschränkt auf die Schreibsessionen (siehe ancestor-Filter aus query.xqm oben).
Welche Bedingung schließt die Kommentar-Noten aus, obwohl sie in tei:text stehen?
Und wie kommen Absender/Empfänger aus dem Header dazu? :)
let $keys := (: ??? :)
(: TODO: Keys deduplizieren, dieselbe Person ist mehrfach getaggt
(Marpurg allein steht 8x im Brief) :)
let $distinct := (: ??? :)
(: TODO: jeden Key zu einem Anzeigenamen "Nachname, Vorname" aufloesen.
Wo liegt dieser Lookup in der Codebase? (Hinweis: crud.xqm holt Dokumente
per ID, der Personendatensatz A00xxxx enthaelt die Ansetzungsform) :)
return
<ul>{
(: ??? :)
}</ul>
};
Werke
declare function local:works($doc as document-node()) as element(ul) {
(: TODO: tei:workName und tei:rs[@type='work'] selektieren, gleiche
Scope-Frage wie bei den Personen :)
let $with-key := (: ??? :)
(: TODO: was passiert mit workName OHNE @key (Tonsezkunst, Musik: Zeitung)?
Ueber @key allein gehen sie verloren. Text-Inhalt als Fallback?
Und warum filtert query.xqm auf string-length(@key) = 7? :)
let $without-key := (: ??? :)
(: TODO: dedupe. Vorsicht: Silvana traegt denselben @key an mehreren
verschiedenen workName-Elementen :)
return
<ul>{
(: ??? :)
}</ul>
};
Orte
declare function local:places($doc as document-node()) as element(ul) {
(: TODO: tei:settlement/@key aus den Schreibsessionen. Sollen Absende-
und Empfangsort aus tei:correspDesc im Header dazu? (Im fertigen
Register: ja, Dresden und Mainz stehen im Briefkopf) :)
let $keys := (: ??? :)
(: TODO: dedupe (Dresden kommt im Header UND in der dateline vor) :)
let $distinct := (: ??? :)
(: TODO: Key zu Ortsnamen aufloesen, analog zu den Personen :)
return
<ul>{
(: ??? :)
}</ul>
};
Wikipedia-Verlinkung (GND aus dem WeGA-Datensatz, dann Wikidata-SPARQL, dann Wikipedia-URL) ist bewusst nicht Teil dieser Seite. Das ist ein eigenes Folgethema und für die Extraktions-Queries nicht nötig.