Sql-und-Xml - Home

Xml lernen

Unicode - Unterstützung als Merkmal des weltweiten Austauschs von Dokumenten

Zeichensätze und ihre interne Darstellung

Jeder über das Netzwerk versendete Datenstrom, jede in den Arbeitsspeicher eingelesene Datei zerfällt in Zeichen als 'kleinsten Einheiten'. Für die interne Darstellung stehen insgesamt nur zwei Werte (ja / nein, 0 / 1, wahr / falsch) zur Verfügung, diese kleinste Informationseinheit wird als ein Bit bezeichnet. Um mit dieser minimalen Codierung bsp. die üblichen Buchstaben zusammenzusetzen und der internen Bit-Darstellung druckbare Zeichen zuordnen zu können, müssen Regeln festgelegt werden, in welchen Blöcken diese 'kleinsten Einheiten' zusammengefaßt werden sollen und welches druckbare Zeichen einem Element dieses Blocks zugewiesen wird. Der Standardblock umfaßt 8 Bit und wird als ein Byte bezeichnet. Mit einem Byte können maximal 2^8 = 256 verschiedene druckbare Zeichen dargestellt werden. Theoretisch könnten solche Zuordnungen von jedem Hardware-Produzenten neu festgelegt werden, dann würde jeder Austausch scheitern. Um den plattformübergreifenden Austausch von Daten zu ermöglichen, müssen deshalb internationale Regelungen getroffen werden, wie lang solche Blöcke sein sollen und welcher internen Bitdarstellung welches druckbare Zeichen zugeordnet wird. Das Ergebnis ist ein Zeichensatz, der mit n Bit bzw. n/8 Byte maximal 2^n verschiedene Zahlen benennt und diesen ebenso viele verschiedene Zeichen zuweist.

Die wohl früheste Regelung stellt der American Standard Code for Information Interchange (ASCII) dar. 1968 wurden vom American National Standards Institute (ANSI) die ersten sieben Bit eines Byte verwendet, um 128 Zeichen, die Groß- und Kleinbuchstaben, arabische Ziffern, die üblichen Satzzeichen sowie einige Sonderzeichen abzubilden. Dieser Zeichensatz stimmt mit dem ISO/IEC 646/1991 überein (siehe ISONETMANUAL-1998.pdf). Die meisten Programmiersprachen fordern, daß zur Definition von eigenen Variablen, Funktionen und Klassen höchstens eine Teilmenge der Ascii-Zeichen verwendet werden darf. Von der International Organization for Standardization (ISO) wurden weitere Zeichensätze verabschiedet, bei welchen die bei einem Byte noch freien oberen 128 Zeichen verschiedenen Kulturen zugeordnet sind. So umfaßt ISO-8859-1 die westeuropäischen Zeichen einschließlich der typisch deutschen Sonderzeichen, ISO-8859-4 'nordeuropäische Zeichen', ISO-8859-5 Kyrillisch und ISO-8859-9 Türkisch. Mit diesen Zeichensätzen lassen sich Html-Dokumente, welche zu einer Kultur gehören, akzeptabel darstellen: Die Html-Elemente nutzen ASCII, also kann die Datei mit jedem Editor, der ASCII speichert, erzeugt werden. Die wenigen benötigten Sonderzeichen (<, &, ', ", >, =) sind ebenfalls im ASCII enthalten. Für den ausgegebenen Text wird die Codierung mit einem der obigen ISO-Werte festgelegt.

Beispiel:
<meta http-equiv="content-type"
	content="text/html; charset=ISO-8859-1" />
Diese Anweisung besagt, daß die Bytes > 127, etwa einer der deutschen Umlaute, gemäß ISO-8859-1 dargestellt werden soll. Der Browser betrachtet die Datei als Byte-unterteilt, verwendet also 8 Bit als Einheit. Fehlt eine solche Anweisung, so verwendet der clientseitige Browser die Standardeinstellung. Das Dokument wird gegebenenfalls fehlerhaft bzw. nicht korrekt lesbar angezeigt, falls es Zeichen aus dem Bereich > 127 enthält. Ebenso kann in den meisten Browsern diese Einstellung überschrieben werden, so daß anstelle der Sonderzeichen Quadrate oder andere unlesbare Ausdrücke erscheinen.

Offenkundig genügen die ISO-Ein-Byte-Zeichensätze nicht, wenn Texte verschiedener Kulturen in einem Dokument erscheinen sollen. Bereits bei Namenslisten im Rahmen universitärer Veranstaltungen können Zeichen fehlen, bei asiatischen, koreanischen oder arabischen Texten, die international ausgetauscht werden müssen, ist die Begrenzung auf den westeuropäisch-amerikanischen Zeichensatz offensichtlich inakzeptabel. Ebenso gibt es einen ständigen Bedarf an neuen Zeichen. Man denke an mathematisch-naturwissenschaftliche Sonderzeichen, die Darstellung historischer Schriften oder die Einführung der €-Währung. Lösungen innerhalb spezieller Programme (etwa Symbole in Word) produzieren neue (Plattform-) Abhängigkeiten und erfordern zusätzlichen internen Code, um die Zeichencodierung in ein druckbares Zeichen umzuwandeln. Deshalb wurden die maximal 256 Zeichen umfassenden 1-Byte-Codierungen durch standardisierte Zeichensätze erweitert, die gemeinsam - durchaus ungenau - als Unicode bezeichnet werden. Die Basis bildet die basic multilingual plane (= BMP) mit einer 2-Byte-Codierung (Double-Byte-Character-Set = DBCS, ISO-10646), die (theoretisch) 2^16 = 65.536 verschiedene Zeichen abdeckt (Einzelheiten siehe Unicode-Standard). Die ersten 256 Zeichen entsprechen ISO-8859-1 und entsprechen den üblichen englisch-westeuropäischen Zeichen einschließlich der deutschen Umlaute. Wenn von Unicode gesprochen wird, ist normalerweise diese Zeichenmenge gemeint. Ferner gibt es eine Erweiterung auf 4 Byte, mit der bis zu 2^32 = 4.294.967.296 Zeichen dargestellt werden können. Jeder Zeichensatz ist eine Teilmenge des folgenden Zeichensatzes, also ASCII ⊂ basic multilingual plane ⊂ 4-Byte-plane. Normative, thematisch gegliederte Listen zu den einzelnen Zeichensätzen sind unter www.unicode.org/charts/ verfügbar. Hierbei handelt es sich jedoch meist um PDF-Dateien mit eingeschränkten Suchmöglichkeiten.

Seit September 2004 existiert eine lokale Darstellung als Html, die als Unicode-Datenbank zur Verfügung steht. Näheres siehe im folgenden Kapitel.

Tatsächlich werden diese Zeichensätze nicht direkt verwendet, sondern es gibt mehrere Unicode transformation format (UTF) - Algorithmen (siehe die UTF-BOM-FAQ). Diese bilden die als Zahlen aufgefaßten Bitfolgen auf eindeutige Byte-Sequenzen ab und legen zu Beginn des Datenstromes mit der Byte Order Mark - Sequenz (BOM) fest, um welche Transformation es sich handelt. Denn in den Unicode-Zeichensätzen sind wenige Zahlen unbenutzt, deren Kombination als BOM genutzt werden kann. Zusätzlich zur Unterscheidung zwischen UTF-8, UTF-16 und dem bislang noch kaum unterstützten UTF-32 gibt es die Unterscheidung zwischen little-endian und big-endian. Bei einem Zwei-Byte-Zeichen kann das most significant byte das erste Byte (little-endian) oder das zweite Byte (big-endian) sein.

Aktuell gibt es die folgenden BOM:

BytesEncoding Form
00 00 FE FFUTF-32, big-endian
FF FE 00 00UTF-32, little-endian
FE FFUTF-16, big-endian
FF FEUTF-16, little-endian
EF BB BFUTF-8

UTF-8 ist ein komprimiertes Format von UTF-16, in welchem Ascii mit einem Byte, viele der gebräuchlichen Sonderzeichen mit 2 Byte und bsp. asiatische Schriftzeichen mit 3 Byte codiert werden. Enthalten UTF-8 - Dateien nur Ascii bzw. prozentual wenige einfache Sonderzeichen, so sind sie nur geringfügig länger als Ascii-Dateien gleichen Inhalts. Enthält eine Datei sehr viel Sonderzeichen oder handelt es sich um einen Text, der in einer außereuropäischen Schriftart codiert ist, so ist die UTF-16 - Codierung dem UTF-8 vorzuziehen.

Die Unterschiedlichkeit dieser Codierungen kann man sich an dem folgenden Beispiel verständlich machen, falls ein Rechner ab Windows2000 zur Verfügung steht. Man speichere mit Notepad eine Datei ab, welche die folgende Sequenz enthält:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Diese Datei wird 26 Byte groß sein. Anschließendes Speichern als Unicode (= UTF-16), Unicode-big-endian oder UTF8 ergibt Dateigrößen von 54 (= 2 * 26 + 2), 54 und 29 (= 26 + 3) Byte. Bei den 2-Byte-Formaten verdoppelt sich die Dateigröße, ferner wird das 2-Byte umfassende BOM an den Dateianfang hinzugefügt. Bei UTF-8 bleibt die Zahl der Zeichen gleich, da diese keine Sonderzeichen enthalten, es wird lediglich das drei Byte umfassende BOM hinzugefügt. Wird das erste A durch Ä ersetzt, ändert sich die Dateigröße der UTF-16-Versionen nicht, UTF-8 wächst auf 30 Byte und ANSI bleibt ebenfalls bei 26 Byte. Ersetzt man B durch das Zeichen ऒ (per Copy und Paste), so zeigt auch das XP-Notepad mit der Standardeinstellung (Font bsp. 'Lucida Console') dieses Zeichen nicht mehr korrekt an. Ändert man den Font auf 'Arial Unicode MS', so wird das Zeichen korrekt dargestellt. Beim Speichern der ANSI-Version wird mitgeteilt, daß Zeichen verloren gehen werden. UTF-16 benötigt weiterhin 54 Zeichen, UTF-8 wächst auf 32 Zeichen, da für dieses Sonderzeichen 3 Byte abgelegt werden. Wenn man mag, kann man sich mit dem in den Windows-Systemen enthaltenen EDIT.Com (per Kommandozeile) die Dateien im rohen Byte-Format direkt ansehen. Bei UTF-16 und A als erstem Buchstaben folgt auf das BOM sofort A, gefolgt von einem Null-Byte (00), bei der big-Endian-Version ist die Reihenfolge dieser Bytes vertauscht. Man kann sich per Markierung mit der rechten Maustaste bsp. das UTF-16-BOM in die Zwischenablage kopieren und es mit EDIT.Com an den Beginn der obigen Alphabet-Sequenz anhängen. Edit.com fügt beim Speichern zwei Byte an, so daß die Datei 30 Byte groß ist. Das anschließende Öffnen mit Notepad zeigt nur noch 14 Zeichen an, die nicht einmal von dem MS Arial Unicode - Font vollständig dargestellt werden. Ergänzt man die obige Ascii-Sequenz, die gleichzeitig eine gültige UTF-8 - Sequenz ist, um die drei UTF-8 - BOM, so zeigt Notepad weiterhin diese 26 Zeichen an.

Zeichendarstellung in Html und Xml

Von den ersten Html-Useragenten wurde lediglich gefordert, daß sie Ascii als Dateicodierung verstehen. Bereits die Latin-1 - Zeichen wurden ausdrücklich über eine Entity-Tabelle eingebunden (siehe die Html 2.0 - Language Specification vom September 1995). Der UserAgent (= Browser) muß keine UTF-8 oder UTF-16-Dokumente verarbeiten können, es wurde jedoch gefordert, daß er die Ascii-Zahldarstellung von Zeichen durch Entities (&#169; = ©) für die meisten der ISO-Lat-1 - Zeichen versteht und diese korrekt darstellt. Englischsprachige Texte können damit direkt getippt werden, wohingegen bereits deutsche Umlaute ständiges Codieren erfordern. Die Verwendung des meta-Elements mit dem Attribut http-equiv="content-type" sowie die weitestgehende Interpretation dieser Angaben durch neuerere Browser entschärfte einerseits dieses Problem für oft genutzte Sonderzeichen. Andererseits wurden mit jeder Html-Version die Listen der namentlich vordefinierten Entities länger. Selbst bei einer vollständigen Unterstützung dieser muß für jedes Sonderzeichen die benannte Version ermittelt und getippt werden (uuml für das deutsche ü, alpha für α). Spätere Browser unterstützten die Codierung mit &#x[Unicode-Word];, so daß einzelne Zeichen hierüber eingefügt werden konnten. Spätestens bei asiatischen Texten, die über die Tastatur eingegeben werden, ist diese Technik nicht mehr vermittelbar. Ein Programm, das eine Tastatureingabe in die zugeordnete, acht Zeichen umfassende &#x76ED; - Entity - Darstellung umschreibt (dies ist das Zeichen 盭), stellt offensichtlich eine Art 'Doppelarbeit' dar. Jeder Xml-Parser muß deshalb Unicode-Eingabe-Streams verarbeiten, ein BOM erkennen und den zugehörigen UTF - Algorithmus anwenden.

Eingabe und Darstellung von Unicode-Zeichen im Editor

Mit dieser fundamentalen Anforderung an Xml-Parser ist jedoch nur das Xml-interne Fundament geschaffen, Unicode vollständig zu unterstützen. Nun ist es Aufgabe von jedem Betriebssystem-Anbieter, (1) Tastaturtreiber bereitzustellen, welche direkte Unicode-Eingaben erlauben, (2) Fonts zu entwickeln bzw. eine Einbindung von Drittanbieter-Fonts zu ermöglichen, welche sämtliche Zeichen der basic multilingual plane (= 2-Byte-Codierung) bereitstellen sowie (3) Editierwerkzeuge so anzupassen, daß die Tastatureingaben direkt als 2-Byte-Codierungen unter Verwendung des Unicode-Fonts ausgegeben werden. Zu letzterem zählt, daß die Editierwerkzeuge nicht nur Ascii-Texte laden und speichern, sondern beim Öffnen des Dokuments dessen BOM auslesen, den Bytestrom dementsprechend transformieren und das Ergebnis mit korrektem BOM speichern. Der Ersteller eines Xml-Dokumentes ist schließlich dafür verantwortlich, daß er das korrekte Tastaturlayout wählt und im Editor einen Font wählt, der die gewünschten Zeichen enthält. Damit ist Xml die erste 'Programmiersprache', in der selbstdefinierte Namen mit fast beliebigen Sonderzeichen erlaubt sind. In wohl jeder anderen Programmiersprache dürfen selbst definierte Namen lediglich Ascii-Zeichen enthalten.

Hinweise für die Xml-Praxis

In Xml wird die gewünschte encoding in der Xml-Declaration festgelegt:
<?xml version='1.0' encoding='UTF-8' ?>
Als Wert für das Attribut sind die UTF-Ausdrücke UTF-8 und UTF-16 sowie alle ISO-encoding-Werte erlaubt.
  • Enthält Ihr Dokument ausschließlich Ascii-Zeichen, da es sich bsp. um einen englischsprachigen Text ohne Sonderzeichen handelt und legen Sie Wert auf eine maximale Abwärtskompatibilität (Anzeige des rohen Textes in einem alten Browser), so speichern Sie das Dokument als Ascii und verzichten auf eine encoding-declaration in der Xml-Declaration.
  • Enthält Ihr Dokument zusätzlich bsp. deutsche Umlaute, so erhalten Sie beim Speichern als Ascii und Aufruf etwa im InternetExplorer eine Fehlermeldung an der Stelle, an welcher zum ersten Mal ein Umlaut auftaucht: 'Im Textinhalt wurde ein ungültiges Zeichen gefunden'. Beachten Sie, daß diese Fehlermeldung auch dann auftaucht, wenn das Sonderzeichen in einem Kommentar oder in einem CDATA - Block steht. Denn in diesem Fall kann der Datenstrom nicht eingelesen werden, ein Bruch der Regeln wohlgeformter Dokumente wird erst später analysiert. In diesem Fall ergänzen Sie entweder encoding durch einen geeigneten Wert, etwa 'ISO-8859-1' oder Sie speichern das Dokument in einem Unicode-Format ab.
  • Das Xml-Standard-Format ist UTF-8, die encoding-declaration ist optional. Da reines Ascii eine Teilmenge von UTF-8 ist, bei welcher lediglich das BOM fehlt, werden Ascii-Texte korrekt verarbeitet, auch wenn die encoding-declaration fehlt. Es darf jedoch keinen Widerspruch geben zwischen BOM und encoding-declaration, daß bsp. die Datei als UTF-8 oder Ascii gespeichert ist und in der encoding-declaration UTF-16 verwendet wird. In diesem Fall wird eine charakteristische Fehlermeldung ausgegeben: 'Wechseln zwischen aktueller und angegebener Verschlüsselung wird nicht unterstützt' (Bsp. IE6).
  • Bei sämtlichen europäischen Texten dürfte UTF-8 die beste Codierung sein, da das Xml-Dokument mit dieser Codierung nur wenig länger als die Ascii-Version ist und alle Sonderzeichen verwendet werden können. Alternativ verwendet man Ascii, einen ISO-encoding - Wert und schreibt zusätzliche, selten benötigte Sonderzeichen über die &#x[Unicode-Word]; - Darstellung als Entity. Enthält der Text ausschließlich Unicode-Zeichen oberhalb von einem Byte und wird dieser Text als UTF-8 gespeichert, so umfaßt die Datei etwa drei Mal soviele Bytes im Vergleich zu den getippten Zeichen. Bei solchen Texten ist Unicode, also UTF-16, die beste Wahl, da pro Zeichen zwei Byte notwendig sind.
  • Für alle Unicode-Versionen ist ein BOM zu Beginn der Datei oder des Datenstroms Pflicht. Dies erledigen Editoren jedoch transparent im Hintergrund. Innerhalb von Xml gibt es weder eine Notwendigkeit noch eine Möglichkeit, zwischen little-endian und big-endian zu unterscheiden. Es genügt deshalb, den Datenstrom als UTF-8 oder UTF-16 zu deklarieren.
  • Werden Sonderzeichen als leere Quadrate, also fehlerhaft angezeigt, so wurde für die Anzeige ein Font gewählt, der nicht alle Unicode-Zeichen implementiert. 'Gewöhnliche' Fonts implementieren nur sehr wenige Zeichen und sind in der Regel kleiner als 500 KB. Der im Windows2000 enthaltene 'MS Arial Unicode' umfaßt dagegen 23 MB. Bei allen Fällen mit diesen 'leeren Quadraten' handelt es sich also nicht um ein Xml-, sondern ausschließlich um ein Problem der Anzeige.

    Nebenbemerkung: Das gleiche Problem taucht bei Access oder MS-Sql-Server auf: Zwar können mit nvarchar (MS-Sql-Server) oder dem Datentyp 'Text' beliebige Unicode-Zeichen eingegeben und abgelegt werden. Wird jedoch der Standardfont nicht angepaßt, so erscheinen in Formularen nur leere Quadrate.
  • Kleine Nebenbemerkung zu Microsoft Word: Kennt man den hexadezimalen Wert eines Unicode-Zeichens, so kann dieser in ein Word-Dokument notiert und markiert werden. Alt+C erzeugt das zugeordnete Unicode-Zeichen, gegebenenfalls muß noch ein passender Font gewählt werden. Ebenso kann ein beliebiges Zeichen einschließlich der gewöhnlichen lateinischen Zeichen markiert und mit Alt+C zur Unicode-Hex-Darstellung gewechselt werden.

© 2003-2014 Jürgen Auer, Berlin.