Donnerstag, 4. Dezember 2008





April 2006
aus Ausgabe: 3.2003
Wohin geht die Reise?
Neuerungen in XML 1.1
von Stefan Heymann

Der XML-Standard hat in diesen Tagen seinen fünften Geburtstag gefeiert. Für die Zeitmaßstäbe in der Branche ein recht langer Zeitraum, vor allem wenn man bedenkt, dass heute noch die Version 1.0 gültig ist und sich XML einer hohen - und steigenden - Verbreitung erfreut. Nach fünf Jahren liegen nun genügend Praxiserfahrungen vor, um noch ein paar letzte größere Korrekturen anzubringen: Die Definition von XML 1.1 befindet sich seit Oktober 2002 im Stadium der Candidate Recommendation, hat also schon einige Hürden der W3C-Standardisierung überwunden. Den neuen Standard und seine Auswirkungen in der Praxis stellt der folgende Artikel vor.


Warum der Versionssprung?
Warum ändert das W3C den Standard? Warum wird dadurch eine neue Versionsnummer erforderlich? Dafür gibt es einige Gründe:
Unicode hat sich weiter entwickelt. Enthielt Unicode 3.0 (auf dem XML 1.0 basiert) noch 49.194 Zeichen, so sind es heute bei Unicode 3.2 schon 95.156 Zeichen und es werden sicher noch mehr (Unicode kann bis zu ca. 1 Million Zeichen definieren). Bereits XML 1.0 hat die Verwendung aller Unicode-Zeichen erlaubt, allerdings nur einen Teil davon in Bezeichnern (Element-Namen, Attribut-Namen, Enumerationen, PI-Targets usw.). XML 1.1 wird nun die Definition der in Bezeichnern erlaubten Zeichen umdrehen: Alles, was nicht explizit verboten ist, wird erlaubt.


XML 1.0 hat die in modernen Computersystemen üblichen Whitespace-Zeichen (Space, Tab, CR, LF) berücksichtigt, aber nicht die in der IBM-Mainframe-Welt üblichen. Das hat dazu geführt, dass in dieser Mainframe-Welt XML-Dateien keine Text-Dateien sind. Sie erfordern also immer eine spezielle Behandlung (Umwandlung von Zeilenwechseln usw.). Daher wird in XML 1.1 das NEL-Zeichen (Newline, U+0085 bzw. #x85) als Whitespace-Zeichen aufgenommen. Und da man schon einmal dabei war, hat man auch gleich das Unicode-Zeilentrennzeichen U+2028 bzw. #x2028 mit aufgenommen.


Offensichtlich wollten viele XML-Autoren die Steuerzeichen im Bereich #x01 bis #x1F in ihre Dokumente aufnehmen. Diese so genannten C0-Controls (mit Ausnahme von Tab, CR und LF, deren Verwendung schon in XML 1.0 erlaubt war) können nun ebenfalls verwendet werden. Damit XML-Dateien aber weiterhin von normalen Texteditoren les- und darstellbar sind, dürfen diese Zeichen nur als Character Reference verwendet werden, also beispielsweise .


Das NUL-Zeichen (#x00) bleibt allerdings weiterhin in jeder Form verboten. Die direkte Aufnahme von Binärdaten in ein XML-Dokument ist also auch in Zukunft nicht möglich. So müssen APIs, die auf nullterminierten Strings basieren, nicht umgeschrieben werden (und das war wohl der Hauptgrund für diese Entscheidung).
Die neue Versionsnummer wurde also erforderlich, weil XML 1.1-Dateien aufgrund dieser Änderungen kein wohlgeformtes XML 1.0 mehr sind. Schauen wir uns die Änderungen im einzelnen an.

Änderungen am Zeichensatz
XML 1.0 erlaubt für das gesamte Dokument die direkte Verwendung praktisch aller Unicode-Zeichen. Nicht verwendet werden dürfen die Surrogat-Blöcke, die Zeichen #xFFFE und #xFFFF sowie die C0-Controls mit Ausnahme von Tab, CR und LF.


In XML 1.1 wird zusätzlich die direkte Verwendung der so genannten C1-Controls (Zeichenbereich #x80 bis #x9F) und des Delete-Zeichens (#x7F) verboten. Ausnahme hier ist das in der IBM-Mainframe-Welt übliche Newline-Zeichen NEL (#x85), das explizit erlaubt ist.
Die C0-Controls dürfen und die C1-Controls müssen zukünftig als Character Reference notiert werden. Ausnahmen sind Tab (#x9), CR (#xD), LF (#xA) und NEL (#x85): Diese Zeichen dürfen direkt verwendet werden. Das NUL-Zeichen #x00 darf weder direkt noch als Character Reference in einer XML-Datei vorkommen.

In Bezeichnern erlaubte Zeichen
Größere Änderungen gibt es bei den Zeichen, die in Bezeichnern (wie Element-Namen, Attribut-Namen, Enumerations-Elementen, Processing Instruction Targets usw.) erlaubt sind. Während XML 1.0 hier eher restriktiv war (alles was nicht erlaubt ist, ist verboten), dreht XML 1.1 dies um: Alles, was nicht verboten ist, ist erlaubt. Dadurch ist es bei zukünftigen Erweiterungen des Unicode-Zeichensatzes nicht mehr erforderlich, den XML-Standard anzupassen.


Da eine verbale Erläuterung der neuen Regeln unnötig kompliziert wäre, hier direkt die Definitionen aus dem XML 1.1-Standard:

[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] |
[#xC0-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] |
[#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] |
[#x3001-#xD7FF] | [#xF900-#xEFFFF]
[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 |
[#x0300-#x036F] | [#x203F-#x2040]
[5] Name ::= NameStartChar NameChar*

Es sind praktisch alle Zeichen erlaubt, außer solchen, die Trennzeichen sind oder als solche benutzt werden könnten. Außerdem wurden Ziffern und Verbindungszeichen (Combining Characters) für den Anfang eines Namens ausgeschlossen.
Auch wenn es in der Praxis eher unüblich ist: Bezeichner dürfen durchaus nicht-ASCII-Zeichen enthalten (das ist auch bei XML 1.0 schon so). Der folgende Ausschnitt ist also (zwar unüblich aber) korrekt:

<höhenmaß>250</h>

Änderungen am Prolog
Da 1.0- und 1.1-Dateien nicht kompatibel sind ist eine Unterscheidung unbedingt nötig. Daher trägt die XML-Deklaration am Beginn jedes XML-Dokuments nun die Versionsnummer 1.1. Beispiel:

<?xml version=1.1 encoding=utf-8 ?>

XML-Dateien, die keine XML-Deklaration haben, werden von allen Parsern als XML 1.0 betrachtet.


Ein XML 1.1-konformer Parser sollte auch XML 1.0-Dateien parsen. (Die W3C-Spezifikation verwendet den Begriff should, er muss also nicht ...). Trotzdem können 1.0-Dokumente nicht einfach durch eine Änderung der Versionsnummer im XML-Prolog zu 1.1-Dokumenten konvertiert werden. Dies geht nur, wenn die 1.0-Datei wohlgeformt (well-formed) oder gültig (valid) ist und keine C1-Controls direkt enthält.
Es ist zulässig, externe Entities und externe DTDs zwischen den Versionen zu mischen. Man kann also eine bereits in Version 1.0 bestehende externe Entity von einem XML 1.1-Dokument aus verwenden.

Zeilenwechsel
XML 1.0 hat nur die Zeichen CR (Carriage Return, #x0D) und LF (Linefeed, #x0A) als Zeilentrennzeichen betrachtet. Dies wird nun geändert (wie oben beschrieben vor allem für Anwender aus der IBM-Mainframe-Welt). Als Zeilentrennung gilt zukünftig:
  • eine CR-LF-Sequenz (#x0D, #x0A)
  • eine CR-NEL-Sequenz (#x0D, #x85)
  • ein einzelnes NEL-Zeichen (#x85)
  • ein einzelnes Unicode-Zeilentrennzeichen (#x2028)
  • Jedes alleinstehende CR-Zeichen (#x0D), dem nicht direkt ein LF (#x0A) oder NEL (#x85) folgt.

Unicode-Normalisierung
Viele Zeichen können mit dem Unicode-Zeichensatz unterschiedlich buchstabiert werden. So kann z. B. ein kleines ä mit dem einzelnen Zeichen U+00E4 (LATIN SMALL LETTER A WITH DIAERESIS) oder als Kombination der beiden Zeichen U+0061 (LATIN SMALL LETTER A) und U+0308 (COMBINING DIAERESIS) dargestellt werden. Letzteres ist die Kombination aus einem kleinen a mit einem Verbindungs-Zeichen, das die beiden Pünktchen enthält.


Das mag zwar in manchen Fällen praktisch sein, erschwert aber den binären Vergleich zweier Strings. Denn selbst wenn diese vom Aussehen her gleich sind, haben sie unterschiedliche binäre Darstellungen.
Um diesen Konflikt aufzulösen, definiert Unicode eine Normalisierung, bei der alle Zeichenkombinationen und Kombinationszeichen zu einem einheitlichen, definierten Zeichen (bzw. Zeichenfolge) konvertiert werden.
Die XML 1.1-Spezifikation verlangt, dass ein XML-Generator nur normalisierten Unicode ausgibt. Ein XML 1.1-Parser soll hingegen in der Lage sein, ein gegebenes Dokument daraufhin zu prüfen, ob es normalisiert ist.


Beide Anforderungen werden mit dem Wort should (sollte) versehen, müssen also genau genommen nicht unbedingt implementiert werden. Trotzdem werden die Entwickler ermutigt, diese Anforderung zu realisieren, damit man sich bei String-Vergleichen nicht um die unterschiedliche Buchstabierung kümmern muss.
Das Problem dabei: Eine solche Normalisierung in Code zu gießen, ist nicht trivial. Dem Algorithmus müssen sämtliche Kombinationsmöglichkeiten und deren Normalisierungs-Form bekannt sein. Um die Sache nicht unnötig einfach werden zu lassen, definiert Unicode (im Technical Report #15) gleich vier Normalisierungs-Formen.
Eine Normalisierung oder wenigstens eine Prüfung darauf stellt also eine hohe Hürde dar. Und solche Algorithmen werden die XML-Parser (die ja aufgrund der Komplexität von XML oftmals nicht besonders performant sind) noch weiter ausbremsen.

Fazit
Obwohl sich Dateien der beiden Versionen sehr ähnlich sehen, sind sie doch inkompatibel zueinander. Die Abweichungen in den Regeln sind zu groß, als dass man leichtfertig mit einem 1.0-Parser ein 1.1-Dokument einlesen sollte oder vice versa. Auf der anderen Seite besteht die Hoffnung, dass XML 1.1 der letzte große Umbau am XML-Standard sein wird.


Dass XML 1.1 das NUL-Zeichen (#x00) weiterhin verbietet, halte ich für eine kluge Entscheidung. Viele Parser verwenden das NUL-Zeichen als String-Ende bzw. als Abschluss des ganzen Dokuments. Diese hätten sonst aufwändig umgeschrieben werden müssen.
Wer die Neuheiten in Version 1.1 nicht unbedingt braucht (NEL-Zeichen für Mainframes, C0-Controls, erweiterte Möglichkeiten für Bezeichner), kann getrost weiterhin XML 1.0-Dateien erzeugen. Allein schon wegen der enormen Menge der in den letzten fünf Jahren erzeugten XML-1.0-Dateien kann man meiner Ansicht nach nicht davon ausgehen, dass es irgendwann nur noch Dateien nach dem neuen 1.1-Standard geben wird.
Es bleibt abzuwarten, was aus der Anforderung zur Normalisierung von XML-Dokumenten bzw. der Prüfung auf Normalisierung beim Einlesen wird. Während die anderen Änderungen für die XML-Parser-Hersteller mit überschaubarem Aufwand in den Griff zu bekommen sind, ist mir im Moment (Ende Februar 2003) keine Implementierung eines 1.1-Parsers bekannt, der die Normalisierungsprüfung durchführt.


Wie bereits erwähnt, ist eine Normalisierung von Unicode-Text nicht einfach zu kodieren. Es bleibt abzuwarten, wer diesen Aufwand betreiben wird. Auch wenn die Gründe für die Normalisierung einleuchtend sind, so wird sie doch zu einer weiteren Performance-Senkung der Parser beitragen.

Wie geht's weiter?
XML 1.1 ist noch kein fertiger Standard. Im Moment befindet sich die Spezifikation noch im Status Candidate Recommendation. Bevor sie zu einer echten W3C-Recommendation werden kann, muss sie noch die Stufe Proposed Recommendation durchlaufen. Dazu ist es unter anderem erforderlich, dass Parser-Implementierungen vorliegen (das W3C erzeugt auf diese Weise keine rein akademischen Standards).


Im Moment sind mir zwei Implementierungen bekannt: RXP von Richard Tobin und Xerces vom Apache XML Project. Beide haben die Unicode-Normalisierung nicht realisiert. Die 1.1-Implementierung von Xerces wird noch als experimentell bezeichnet. Bei Microsoft (MSXML) und den diversen Parser-Projekten für Delphi ist jedenfalls Funkstille, was XML 1.1 anbelangt.


Bis XML 1.1 also wirklich zum Einsatz kommt, kann noch einige Zeit vergehen. Und ob die Normalisierung so kommen wird, wie im Moment geplant, wird man noch sehen.

Links und Literatur


    Hat Ihnen dieser Artikel gefallen? Dann abonnieren Sie das Entwickler Magazin direkt über unser Online-Formular.

zur vorherigen Seite
zurück
an den Anfang der Seite
nach oben
Diesen Artikel drucken
drucken
Diesen Artikel weiterempfehlen
empfehlen




Software & Support Verlag GmbH