Zusammenhängende XML-Dateien syntaxgesteuert editieren

Das syntaxgesteuerte Editieren von XML-Dateien ist eine feine Sache. Der Editor weiß, welche Elemente mit welchen Attributen an welchen Stellen erlaubt sind, und er haut dem Anwender auf die Finger, wenn der etwas versucht, was die Document Type Definition (DTD) oder das XML-Schema verbieten.

Editieren mit Emacs/PSGML

Seit rund 20 Jahren verwende ich dazu den Editor Emacs zusammen mit dem sogenannten Major mode PSGML. Unter openSUSE-Linux gehört beides bequemerweise zum Lieferumfang – auch wenn den openSUSE-Leuten die Integration nicht so ganz gelungen ist und man einen weiteren, nicht so mächtigen SGML-Modus per Hand löschen muß. Auch für alternative Betriebssysteme wie Microsoft Windows sind Emacs und PSGML verfügbar.

Ja, klar, gelegentlich habe ich immer wieder mal nach einer moderneren Alternative geguckt, besonders, seit es XML-Schema gibt, mit dem PSGML nichts anzufangen weiß. Bis jetzt habe ich aber nichts gefunden, das erstens frei verfügbar ist und zweitens ähnlich mächtig und flexibel wie Emacs/PSGML daherkommt.)

Ein Beispieldokument

Der folgende XML-Quelltext zeigt ein einfaches Beispieldokument in der Datei A.xml. Welche Regeln darin gelten, legt die DOCTYPE-Deklaration fest (siehe Hervorhebung). Im vorliegenden Fall verrät sie, daß es sich um ein DocBook-Dokument handelt. Ein syntaxgesteuerter Editor wie Emacs/PSGML liest die DocBook-DTD und sorgt beispielsweise dafür, daß innerhalb eines section-Elements title und para in der richtigen Reihenfolge stehen.

version="1.0" encoding="UTF-8"?>
article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd">

<article>

 <section>
  <title>Erstes Kapitel</title>
  <para>Dies ist der Text des ersten Kapitels.</para>
 </section>

 <section>
  <title>Zweites Kapitel</title>
  <para>Dies ist der Text des zweiten Kapitels.</para>
 </section>

</article>

Zusammenhängende Dokumente

Ist ein Dokument länger als unser Minibeispiel, möchte man es womöglich auf mehrere Dateien aufteilen. XML ermöglicht das mit Hilfe von Entities. Eine Entity hat einen Namen und einen Wert. Beispielsweise können wir eine Entity namens anhang definieren, die als Wert den Text eines Anhangs unseres Dokuments enthalten soll.

Das Einfügen des Anhangs in das Dokument ist sehr einfach und übersichtlich, weil wir nur die entsprechende Entity-Referenz &anhang; hinzuschreiben brauchen. Das Ende der Datei sieht so aus:

 ...
 </section>

 &anhang;

</article>

Der Wert der Entity wird an der Stelle eingefügt, an der die Entity-Referenz steht.

Diesen Wert haben wir aber noch gar nicht definiert. Das machen wir in der DOCTYPE-Deklaration, die wir dazu »ein wenig« erweitern:

article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd" [
 <!--ENTITY anhang "
                   <title>Anhang</title>
                   <para>Dies ist der Text des Anhangs.</para>
                  </appendix>">
]>

Damit haben wir allerdings nichts gewonnen, denn der Text des Anhangs steht im Hauptdokument statt in einer separaten Datei, und von einer Vereinfachung kann angesichts der aufgeblähten und unübersichtlichen DOCTYPE-Deklaration keine Rede sein.

Aber eines sieht man doch, nämlich wie eine ENTITY-Anweisung den Namen und den Wert einer Entity festlegt. Der Wert ist eine durch doppelte Anführungszeichen begrenzte Zeichenfolge, die sich in unserem Fall über mehrere Zeilen erstreckt.

Statt den Wert der Entity hinzuschreiben, kann man aber auch angeben, daß sich er sich in einer Datei befindet. Das geht so:

article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd" [
 <!--ENTITY anhang SYSTEM "B.xml">
]>

Das sieht schon besser aus. Mit dieser Definition wird ein XMP-Prozessor jedes Vorkommen von &anhang; in der Datei A.xml durch den Inhalt von B.xml ersetzen.

Eingebundene Dateien editieren

So weit, so gut. Weniger schön ist allerdings, daß wir B.xml nicht editieren können, jedenfalls nicht syntaxgesteuert. Das ist ja auch kein Wunder, denn B.xml enthält nur den reinen Text des Anhangs und keinerlei Hinweis auf eine DTD. Eine DOCTYPE-Deklaration, an der PSGML die zu verwendende DTD erkennen könnte, ist hier nicht erlaubt, weil sie ja mit in das Gesamtdokument integriert und dort zu einem Fehler führen würde. Außerdem lieferte eine DOCTYPE-Deklaration gar nicht genug Informationen. Ein syntaxgesteuerte XML-Editor muß nicht nur wissen, welche DTD gilt, sondern auch, an welcher Stelle die Entity in den übergeordneten XML-Baum eingefügt wird. In unserem Beispiel befinden wir uns im Element article hinter einem section-Element. Davon weiß B.xml aber nichts.

Glücklicherweise können wir diese Informationen in der XML-Datei unterbringen und zwar in einem Kommentar, aus dem sich PSGML eine ganze Reihe von Einstellungen holt. Ein Aufruf von SGML → File Options → Save File Options im Emacs erzeugt diesen Kommentar am Ende der Datei. Hier ein Beispiel:

<!-- Keep this comment at the end of the file
Local variables:
mode: xml
sgml-omittag:nil
sgml-shorttag:nil
sgml-namecase-general:nil
sgml-general-insert-case:lower
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

Interessant ist die hervorgehobene Zeile; wir ersetzen sie durch diese hier:

sgml-parent-document:("A.xml" "article" "appendix")

Diese Anweisung verrät PSGML dreierlei:

  1. Das übergeordnete Dokument ist A.xml. Die dort geltende DTD gilt auch hier.
  2. Die aktuelle Datei, also B.xml, wird in ein article-Element eingefügt.
  3. Die aktuelle Datei muß ein einziges appendix-Element enthalten.

Voilá, und damit geht es! Wir können die Datei jetzt syntaxgesteuert editieren und den Schatz der DocBook-Elemente heben.

Wie man sieht, geht die sgml-parent-document-Anweisung davon aus, daß die aktuelle Datei in ein ganz bestimmtes übergeordnetes Dokument an einer ziemlich genau bestimmten Stelle eingebunden wird. In der Praxis wird das meistens auch so sein. Dennoch kann man die Datei mittels Entity-Referenzen durchaus an mehreren und unterschiedlichen Stellen in das Gesamtdokument einfügen, solange letzteres dadurch syntaktisch korrekt bleibt. Ein XML-Prozessor kümmert sich ja nicht um das, was in irgendeinem Kommentar steht.

Eclipse

Eclipse-Nutzer können übrigens ebenfalls einen leistungsfähigen XML-Editor einsetzen, sofern sie das WTP-Paket installiert haben. Dieser XML-Editor kann nicht nur anhand einer DTD, sondern auch gemäß eines XML-Schemas editieren. Er kommt sogar mit XML-Katalogen klar – ein Thema, das ich aus diesem Beitrag übrigens bewußt herauslasse. Das Bearbeiten von verknüpften Fragmentdateien hat der Eclipse-XML-Editor allerdings nicht drauf. Sehr schade! Ich habe dazu eine Fehlermeldung geschrieben. Wer mag, kann für eine Erweiterung votieren. Bis auf weiteres werde ich aber wohl bei der bewährten Kombination Emacs/PSGML bleiben müssen.

Weblinks

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s