XML-Know How

Namespaces in XML

Sicher ist Ihnen schon aufgefallen, dass alle XSD-Elemente in unseren Beispielen mit »xs:« beginnen. Dieses sogenannte Namespace-Prefix kennzeichnet XML-Elemente, die konzeptionell zusammengehören und in einer gemeinsamen DTD oder einem gemeinsamen Schema deklariert wurden. Solche zusammengehörigen Elemente mit ihren Attributen bilden einen sogenannten Namespace.

Namespaces sollen Konflikte zwischen Elementen und Attributen gleichen Namens aus verschiedenen DTDs oder Schemas verhindern, die gemeinsam in einem XML-Dokument verwendet werden. Das kann bei der Mischung verschiedener XML-Dokumente, bei der Verwendung von Standard-XML (z. B. MathML für Formeln) in eigenen Dokumenten und auch bei Schema-Dokumenten selbst vorkommen, deren Mischung von Frameworks wie ISO/IEC 19757 vorgesehen ist.

Die Verwendung von Namespaces ist seit 1999 vom W3C als Recommendation normiert.

DTDs unterstützen das Namespace-Konzept nicht durch besondere Vorkehrungen, so dass seine Umsetzung per DTD ziemlich umständlich ist. Anders dagegen XSD. Daher sei an dieser Stelle etwas genauer auf Namespaces eingegangen.

Namespaces und Namespace-Prefixe werden immer mit einem xmlns-Attribut festgelegt, das jedem XML-Element beigefügt werden kann. Gemäß der XSD-Spezifikation muss jede Software, die XSD-kompatibel ist, dieses Attribut von sich aus erkennen und auswerten können.

In unseren XSD-Beispielen wurde mit dem xmlns-Attribut des <xs:schema>-Elements der Namespace für die XSD-Elemente definiert:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

Man sieht auf den ersten Blick, dass mit dem Attributwert auf die W3C-Website von XML-Schema verwiesen wird. Damit wird nachvollziehbar, von wem die XSD-Elemente definiert wurden. Außerdem wird durch die Erweiterung des xmlns-Attributnamens um »:xs« angegeben, dass alle Elemente, die zu diesem Namespace gehören, mit dem Namespace-Prefix »xs:« beginnen sollen.

Technisch gesehen handelt es sich bei der Webadresse um einen URI, einen Unique Resource Identifier, mit dem eine weltweit eindeutige Benennung des Namensraums möglich ist.

Ein URI kann entweder als URL (Unique Ressource Locator) auftreten, also die Form einer Webadresse annehmen, denn jeder Webadresse ist weltweit eindeutig ein Inhaber zugeordnet. Oder es wird ein URN verwendet (Unique Ressource Name). Auch URNs müssen Codes sein, die von einer Behörde so vergeben werden, dass der juristische Eigentümer identifizierbar ist. Das ist z. B. bei ISBNs der Fall. Ein URN besteht aus der Angabe »urn« gefolgt von der Angabe des Codetypes (hier »isbn«) und dann der eindeutigen Kennung (hier die ISBN mit Landes- und Verlagskennung), jeweils durch »:« getrennt:

xmlns:dtv="urn:isbn:3-423"

Der Aufbau des xmlns-Attributes sieht also prinzipiell so aus:

xmlns:Namespace-Prefix="URI"

Welches Prefix verwendet wird, ist freigestellt, solange es nicht mit »xml« beginnt. Ein XSD-Parser verwendet intern immer den vollen URI als Namespace, das Prefix ist nur ein Platzhalter, der verhindert, dass die XML-Dokumente für Menschen noch schwerer lesbar werden. Es ist wichtig, dass in einem XML-Dokument nicht ein und dasselbe Prefix für verschiedene Namensräume verwendet wird.

Das Namespace-Prefix darf auch weggelassen werden:

xmlns="http://www.w3.org/2001/XMLSchema"

In einem Container-Element, das ein xmlns-Attribut ohne Prefix-Angabe trägt, sind alle Unterelemente ohne Prefix dem dort angegebenen Namespace zugeordnet, jedenfalls solange bei den Subelementen keine abweichende Zuordnung mit einem weiteren xmlns-Attribut getroffen wird oder Subelemente ein Namespace-Prefix tragen.

Ein Beispiel-XML-Dokument verdeutlicht diese auf den ersten Blick komplizierte Regel:

<?xml version="1.0"?>
<bookshop xmlns=‘http://www.beispiel1.org/bookshop‘
xmlns:std=‘http://www.beispiel2.org/bibliostandard‘>
<book>
<title>Cheaper by the Dozen</title>
<std:isbn>123456789X</std:isbn>
<notes>
<p xmlns=‘http://www.w3.org/1999/xhtml‘>
This is a <i>funny</i> book!
</p>
</notes>
</book>
</bookshop>

Man sieht bei <bookshop>, dass ein Element mehrere xmlns-Attribute haben kann, allerdings müssen sie sich durch ihre Prefix-Festlegungen unterscheiden.

In <bookshop> werden zwei Namespaces zugewiesen: xmlns=‘http://www.beispiel1.org/bookshop‘ enthält keine Festlegung eines Namespace-Prefix. Das heißt: <bookshop> und alle Elemente in <bookshop>, die kein Prefix tragen und auch nicht durch ein eigenes xmlns-Attribut abweichend zugewiesen werden, gehören zum Namespace »http://www.beispiel1.org/bookshop«.

xmlns:std=‘http://www.beispiel2.org/bibliostandard‘ legt fest, dass <bookshop> und alle Elemente in <bookshop>, falls sie das Namespace-Prefix »std« tragen, zum Namespace »http://www.beispiel2.org/bibliostandard« gehören. Im Beispiel trifft das auf das <isbn>-Element zu, das als <std:isbn> auftritt. Für die ISBN-Angabe wird also ein <isbn>-Element verwendet, das von einem (im Beispiel fiktiven) bibliographischen Standard mit eigener DTD oder XSD festgelegt wurde. Grund dafür könnte sein, dass der Standard schon den XSD-Datentyp für ISBNs enthält.

In den <notes> soll nun der Einfachheit halber XHTML-Code verwendet werden. Auch für diesen Code gibt es einen eigenen Namespace und eine eigene DTD bzw. XSD. Er beginnt mit einem <p> Element, das ein xmlns-Attribut mit dem XHTML-Namespace enthält, aber ohne Prefix-Angabe. Damit gilt: dieses Element <p> und alle Elemente in diesem <p>, die kein Namespace-Prefix tragen und nicht durch ein eigenes xmlns-Attribut abweichend zugewiesen werden, gehören zum XHTML-Namespace.

Diese Methode ließe sich beliebig fortsetzen. Als konkretes Resultat haben wir ein Dokument, das Elemente aus drei verschiedenen Namensräumen enthält: bookshop, bibliostandard und XHTML. Für jeden Namensraum gibt es eine eigene XSD oder DTD. Wie man dafür sorgt, dass ein XML-Dokument von mehreren XSDs validiert wird, erfahren Sie weiter unten im Abschnitt Aufruf von XSD.