>> Inhaltsverzeichnis >> Artikel Dateiformat

Von XML zu SML

Die Aufgabe Dateien für die Initialisierung, beziehungsweise Konfiguration eines Frameworks bereitzustellen, ist nicht ganz trivial. Weil das Framework eine Vielzahl von Plugins besitzen kann, deren Konfigurationsoptionen in den gleichen Dateien abgelegt werden sollen wie die restliche Konfiguration. Anzahl, Struktur, Typ und Benennung dieser Daten ist zur Entwurfszeit jedoch unbekannt. Eventuell sind die Plugins, mit denen das Framework arbeiten wird, zu diesem Zeitpunkt auch noch gar nicht geschrieben. Um unter diesen Umständen überhaupt im Voraus eine sinnvolle DTD oder Schema angeben zu können, ist es nur logisch sich auf natürliche Eigenschaften der Variablen zurückzuziehen. Stabile Eigenschaften wie beispielsweise der Datentyp einer Variablen sind geeignet um eine Struktur abzuleiten, welche vorhersagbar ist, weil sie durch stabile syntaktische Eigenschaften von PHP diktiert werden.

Weil PHP nicht streng typisiert ist und Referenzen, sowie Objekte per Definition kein Teil dieser Konfiguration sein dürfen, bleiben die Menge der skalaren Variablen und die Menge der Datenfelder. Dementsprechend werden analog zwei verschiedene Arten von Knoten definiert. Für die Darstellung skalarer Variablen soll der Tag "scalar" eingeführt werden. Dieser darf lediglich CDATA-Abschnitte enthalten – was gerade einem skalaren Kontext entspricht – jedoch keine weiteren Tags, respektive Elemente. Für die Darstellung von Datenfeldern soll der Tag "array" eingeführt werden. Dieser darf wiederum keine CDATA-Bereiche enthalten, sondern lediglich weitere Tags. Diese Tags repräsentieren die Elemente des Datenfelds. Weil XML ein eindeutiges Wurzelelement verlangt, wird zudem der Tag "root" eingeführt. Weitere Tags werden nicht benötigt.

Betrachten Sie das folgende Beispiel, welches zwei Datenfelder darstellt.

<?xml version="1.0" ?>
<!DOCTYPE example SYSTEM "example.dtd">
<root>
	<array name="a">
		<array name="0">
			<scalar name="a"><![CDATA[wert]]></scalar>
			<scalar name="b"><![CDATA[wert]]></scalar>
			<scalar name="c"><![CDATA[wert]]></scalar>
		</array>
		<array name="1">
			<scalar name="a"><![CDATA[wert]]></scalar>
			<scalar name="c"><![CDATA[wert]]></scalar>
		</array>
	</array>
	<array name="b">
		<array name="0">
			<scalar name="q"><![CDATA[wert]]></scalar>
			<scalar name="r" />
			<scalar name="s"><![CDATA[wert]]></scalar>
			<scalar name="t"><![CDATA[wert]]></scalar>
		</array>
	</array>
</root>

An diesem Beispiel fallen einige Besonderheiten auf. Erstens ist das Element "root" völlig ohne semantische Bedeutung. Es existiert einzig und allein, weil die Syntax es erfordert.

Etwas künstlich wirken auch die leeren Tags. Sie sind zwar enthalten, aber es ist nicht ganz klar, wie diese in Bezug auf Variablen interpretiert werden sollen. PHP erfordert keine Definition von Variablen vor der ersten Verwendung. Eine Initialisierung einer zuvor nicht existierenden Variable, geschweige einer Konstante, mit "null" ist somit nicht wirklich sinnvoll. Zumal in einer Konfigurationsdatei ein null-Wert semantisch keinen Sinn machen wird. Daher soll per Konvention festgelegt werden, dass auf leere Tags komplett verzichtet werden sollte. Zugriffe auf leere oder nicht existierende Tags werden gemäß der in PHP üblichen Konventionen zu boolean "false" ausgewertet.

Weiterhin ist absehbar, dass diese Darstellung bei größeren Datenmengen unübersichtlich werden könnte. Betrachtet man beispielsweise den Fall, dass ein Datenfeld möglicherweise 50 oder mehr Einträge aufweist, welche zudem eventuell noch tief verschachtelt sind und große CDATA-Abschnitte mit mehreren Zeilenumbrüchen enthalten, dann ist anzunehmen, dass die Lesbarkeit beeinträchtigt wäre. Es wäre für die Lesbarkeit also von Vorteil, wenn aus einem End-Tag direkt ablesbar wäre, welches Element denn nun gerade geschlossen wurde.

Die gesonderte Kennzeichnung der CDATA-Abschnitte, könnte ebenfalls die Lesbarkeit beeinträchtigen, zumal sich der Sinn für den XML-unerfahrenen Laien nicht trivial erschließen muss. Zudem verlangen die zuvor getroffenen Festlegungen explizit, dass an dieser Position ohnehin gar nichts anderes als ein CDATA-Abschnitt folgen darf, weshalb eine Auszeichnung keinen echten Mehrwert bringt, sondern wiederum lediglich eine syntaktische Ursache hat. Es gibt einen seltenen Ausnahmefall, nämlich dass der CDATA-Abschnitt einen schließenden "scalar"-Tag enthält. Diese Fall kann jedoch auch mit Hilfe von Entities umgangen werden, sodass die Kennzeichnung insgesamt obsolete ist.

Abschließend soll die Schreibweise der Tags betrachtet werden. Beispielsweise die Bezeichnung "<array name="b">". Diese Schreibweise könnte auf Laien, überfrachtet und unnötig kompliziert wirken. Denn: dass es sich um ein Datenfeld handeln muss, wird bereits aus der Struktur des Elements deutlich, weil es nur ein einziges anderes Element gibt. Der Tag "scalar" kann aber aus rein syntaktischen Gründen an dieser Stelle gar nicht stehen, weil dieser keine Tags, sondern nur CDATA enthalten darf. Extra zu erwähnen, dass es sich um ein Datenfeld handelt ist somit im Grunde überflüssig. Das Attribut "name" ist allen Tags gemeinsam. Dies ergibt sich zwangsläufig aus syntaktischen Eigenschaften von PHP. Das Attribut entspricht also dem Bezeichner der Variable in PHP. Intuitiver wäre es statt er Bezeichnung "array" oder "scalar" den Bezeichner der Variablen als Tag zu benutzen. Analog gilt die gleiche Betrachtung für den Tag "scalar".

Berücksichtigt man alle diese Einwände so lässt sich folgende vereinfachte Darstellung gewinnen.

<a>
	<0>
		<a>wert</a>
		<b>wert</b>
		<c>wert</c>
	</0>
	<1>
		<a>wert</a>
		<c>wert</c>
	</1>
</a>
<b>
	<0>
		<q>wert</q>
		<s>wert</s>
		<t>wert</t>
	</0>
</b>

Auch ohne umfangreiche Erläuterung ist erkennbar, dass beide Varianten inhaltlich das Gleiche ausdrücken. Ebenso sollte vermutlich keine Diskussion darüber erforderlich sein, welche der beiden Schreibweisen intuitiver erfassbar, oder leichter lesbar wäre.

Aufgrund ihrer syntaktischen Eigenschaften ist diese Variante jedoch kein wohlgeformtes XML-Dokument mehr. Beispielsweise gibt es mehr als ein Wurzelelement und zudem ist "0" in XML kein gültiger Name für einen Tag. Es war somit notwendig eine andere Bezeichnung zu wählen. Diese Bezeichnung ist "SML" für "simple markup language", in Anlehnung an "XML" ("eXtensible markup language").

Autor: Thomas Meyer, www.yanaframework.net