XML/Regeln/Namensräume und Validierung

Aus SELFHTML-Wiki
< XML‎ | Regeln
Wechseln zu: Navigation, Suche

Dieser Artikel von Franz-Josef Herpers erschien am 28.02.2000 im Selfhtml-aktuell-Bereich. Er beschäftigt sich mit den Problemen der Validierung bei XML-Dokumenten, die Gebrauch von XML-Namensräumen machen. Kenntnis des Namensraumkonzepts von XML wird vorausgesetzt. Das XML-Namensraumkonzept wird nicht im Detail behandelt.

Der Sinn von XML-Namensräumen

XML-Namensräume dienen dazu, Namenskonflikte und Mehrdeutigkeiten in XML-Dokumenten zu vermeiden, die Elemente aus zwei (oder mehr) Dokumenttyp-Definitionen (DTD) enthalten. Durch die Bindung an einen Uniform Resource Identifier (URI) werden potentiell mehrdeutige Namen an einen Namensraum gebunden und auf diese Weise qualifiziert. Ein Namensraum ist also nichts anderes als eine Sammlung von Namen für Elementtypen und Attribute, die über einen URI eindeutig identifizierbar ist. Namensräume, die in einem Dokument verwendet werden, müssen im XML-Dokument deklariert werden. Dabei wird einem sogenannten Namensraum-Präfix der URI des Namensraums zugewiesen. Ein Element oder Attribut aus dem Namensraum wird dann über das Namensraum-Präfix qualifiziert. Das Namensraum-Präfix dient dabei als Abkürzung des URI.

XML-Dokument mitarbeiterliste.xml
<?xml version="1.0" encoding="iso-8859-1"?>

<ma:mitarbeiterliste
       xmlns:ma="http://www.meinServer.de/adresse"
       xmlns:edv="http://www.meinServer.de/rechner">
  <ma:mitarbeiter>
    <ma:name>Dieter Thomas Heck</ma:name>
    <ma:adresse>
      <ma:strasse>Hitstr. 7</ma:strasse>
      <ma:ort>12435 Berlin</ma:ort>
    </ma:adresse>
    <edv:rechner>
      <edv:name>Saturn</edv:name>
      <edv:adresse>127.98.76.35</edv:adresse>
  </edv:rechner>
  </ma:mitarbeiter>
  <ma:mitarbeiter>
    <ma:name>Fritz Walter</ma:name>
    <ma:adresse>
      <ma:strasse>Am Stadion 5</ma:strasse>
      <ma:ort>10115 Berlin</ma:ort>
    </ma:adresse>
    <edv:rechner>
      <edv:name>Rivaldo</edv:name>
      <edv:adresse>156.97.234.98</edv:adresse>
    </edv:rechner>
  </ma:mitarbeiter>
</ma:mitarbeiterliste>
Das XML-Dokument enthält neben den Namen und Adressen der Mitarbeiter einer Firma auch die Daten des Rechners, mit denen der jeweilige Mitarbeiter arbeitet. Um den Namenskonflikt bezüglich der Elemente <name> und <adresse> zu vermeiden, werden im Wurzelelement zwei Namensräume deklariert. Der erste bindet alle Element-Namen zur Auszeichnung der Mitarbeiterdaten, der zweite alle Element-Namen zur Rechneridentifikation. Mittels der zugewiesenen Namensraum-Präfixe ma und edv werden dann die Element-Namen im XML-Dokument unterschieden.

Das Problem: Namensräume und Validierung

Der Namensraum-URI muss nicht auf eine real existierende Web-Ressource verweisen, insbesondere nicht auf eine DTD, die dem Namensraum zugeordnet ist. Die Namensraum-Deklaration hat keinerlei Verweisfunktion und der URI ist lediglich ein eindeutiger, formaler Bezeichner für den Namensraum. Durch eine Namensraum-Deklaration wird keinerlei Verbindung zwischen einem Namensraum und den Deklarationen für die Elemente und Attribute des Namensraums geschaffen. Allgemeiner formuliert: Namensraumkonzept und Validierungskonzept von XML sind unabhängig voneinander.

Dies bedeutet konkret, dass einige Dinge zu beachten sind, wenn Sie gültige XML-Dokumente erzeugen möchten, die Namensräume verwenden.

Verwendung von Namensräumen in gültigen XML-Dokumenten

Sollen Ihre XML-Dokumente, die Namensräume verwenden, gültig sein, müssen die Elementtypen und Attribute, welche einem Namensraum zugeordnet sind, über einen Qualified Name deklariert werden (d. h. mit Namensraum-Präfix). Zudem müssen auch die xmlns-Attribute, die zur Kennezichnung von Namensraum-Deklarationen dienen, in der DTD deklariert werden.

Ungültiges XML-Dokument
<?xml version="1.0" encoding="iso-8859-1"?>

<!DOCTYPE notiz [
  <!ELEMENT notiz (#PCDATA)>
  <!ATTLIST notiz style CDATA #IMPLIED>
]>

<notiz html:style="font-color:red" xmlns:html="http://www.w3.org/TR/REC-html40">
  Dieses Dokument ist leider nicht gültig!
</notiz>
Gültiges XML-Dokument
<?xml version="1.0" encoding="iso-8859-1"?>

<!DOCTYPE notiz [
  <!ELEMENT notiz (#PCDATA)>
  <!ATTLIST notiz html:style CDATA #IMPLIED
                  xmlns:html CDATA #FIXED "http://www.w3.org/TR/REC-html40"
  >
]>

<notiz html:style="font-color:red" xmlns:html="http://www.w3.org/TR/REC-html40">
  Dieses Dokument ist gültig!
</notiz>
Dem Wurzelelement notiz ist das Attribut style aus dem html-Namensraum zugeordnet. Das Attribut wird über das Präfix html qualifiziert und der Namensraum im Wurzelelement deklariert. In der DTD ist dieses Attribut mit Präfix zu deklarieren: <!ATTLIST notiz html:style CDATA #IMPLIED>. Darüber hinaus muss auch das xmlns-Attribut, welches zur Deklaration des Namensraums verwendet wird, in der DTD deklariert werden. Dies kann mittels einer Attribut-Vorgabe in Kombination mit dem Schlüsselwort #FIXED erfolgen. Dadurch lässt sich sicherstellen, dass im Wurzelelement notiz immer eine Namensraum-Deklaration für den HTML-Namensraum erfolgt, auch wenn sie nicht explizit angegeben wird.

Leider funktioniert dies nicht in allen Parsern. Wer auf Nummer sicher gehen will, muss deswegen den Namensraum immer auch noch im Wurzelelement deklarieren.


mitarbeiterliste.xml mit interner DTD
<?xml version="1.0" encoding="iso-8859-1"?>

<!DOCTYPE ma:mitarbeiterliste [
  <!ELEMENT ma:mitarbeiterliste (ma:mitarbeiter+)>
    <!ATTLIST ma:mitarbeiterliste xmlns:ma   CDATA #FIXED "http://www.meinServer.de/adresse"
                                  xmlns:edv CDATA #FIXED "http://www.meinServer.de/rechner"
    >
  <!ELEMENT ma:mitarbeiter (ma:name, ma:adresse, edv:rechner)>
  <!ELEMENT ma:adresse (ma:strasse, ma:ort)>
  <!ELEMENT edv:rechner (edv:name, edv:adresse)>
  <!ELEMENT ma:name (#PCDATA)>
  <!ELEMENT ma:strasse (#PCDATA)>
  <!ELEMENT ma:ort (#PCDATA)>
  <!ELEMENT edv:name (#PCDATA)>
  <!ELEMENT edv:adresse (#PCDATA)>
]>

<ma:mitarbeiterliste
       xmlns:ma="http://www.meinServer.de/adresse"
       xmlns:rech="http://www.meinServer.de/rechner">
  <ma:mitarbeiter>
    <ma:name>Dieter Thomas Heck</ma:name>
    <ma:adresse>
      <ma:strasse>Hitstr. 7</ma:strasse>
      <ma:ort>12435 Berlin</ma:ort>
    </ma:adresse>
    <edv:rechner>
      <edv:name>Saturn</edv:name>
      <edv:adresse>127.98.76.35</edv:adresse>
  </edv:rechner>
  </ma:mitarbeiter>
  <ma:mitarbeiter>
    <ma:name>Fritz Walter</ma:name>
    <ma:adresse>
      <ma:strasse>Am Stadion 5</ma:strasse>
      <ma:ort>10115 Berlin</ma:ort>
    </ma:adresse>
    <edv:rechner>
      <edv:name>Pluto</edv:name>
      <edv:adresse>156.97.234.98</edv:adresse>
    </edv:rechner>
  </ma:mitarbeiter>
</ma:mitarbeiterliste>
Beachten Sie: Für gültige Dokumente fordert die XML-Empfehlung, dass der DTD-Name mit dem Namen des Wurzelelements übereinstimmt. Ist auch der Name des Wurzelelements über ein Präfix qualifiziert, so muss auch der DTD-Name dieses Präfix berücksichtigen.

Namensräume in der DTD

In der DTD werden Namensräume nicht als solche erkannt. Für einen XML-Parser sind die Namensraum-Präfixe in einer DTD nicht Stellvertreter des Namensraum-URI, sondern lediglich ein Teil des Element- oder Attribut-Namen. Mit anderen Worten: eine DTD, in der Elementtypen aus zwei Namensräumen deklariert werden, "weiss" nichts davon, dass sie es mit zwei Namensräumen zu tun hat. Das folgendes Beispiel verdeutlicht diesen Sachverhalt.

Beispiel
<?xml version="1.0"?>

<!DOCTYPE ns1:notiz [
  <!ELEMENT ns1:notiz (ns2:notiz)>
    <!ATTLIST ns1:notiz xmlns:ns1 CDATA #FIXED "http://www.meinServer.de">
  <!ELEMENT ns2:notiz EMPTY>
    <!ATTLIST ns2:notiz xmlns:ns2 CDATA #FIXED "http://www.meinServer.de">
]>

<ns1:notiz xmlns:ns1="http://www.meinServer.de">
  <ns2:notiz xmlns:ns2="http://www.meinServer.de"/>
</ns1:notiz>
Die beiden in der DTD deklarierten Elementtypen besitzen den gleichen lokalen Namen notiz, unterscheiden sich jedoch im Präfix (ns1 und ns2). Trotzdem gehören Sie zum selben Namensraum, da das Präfix nur ein Stellvertreter (Abkürzung) der Namensraum-URI ist. Entscheidend für die Identität von Namensräumen ist der Namensraum-URI und der ist für beide Elemente gleich. Dies gilt jedoch nicht innerhalb von DTDs! Aus Sicht der DTD werden zwei unterschiedliche Elementtypen (nämlich ns1:notiz und ns2:notiz) deklariert. Somit ist dieses Dokument gültig. Würde innerhalb einer DTD eine Zuordnung von Namensraum-Präfixen zu Namensraum-URIs erfolgen, würde ein validierender Parser beide Element-Namen als gleich betrachten und das Dokument für ungültig erklären, da ein Elementtyp in einer DTD nur einmal deklariert werden darf.

Ausblick: XML-Schema und Namensräume

Direkte Unterstützung von Namensräumen bietet XML-Schema, die vom W3C am 02. Mai 2001 als Empfehlung verabschiedete Schemasprache für XML-Dokumente. Ein XML-Schema definiert nicht nur die Struktur eines XML-Dokuments, sondern kann gleichzeitig auch Namensräume bevölkern. Sie können in XML-Schema – im Unterschied zur DTD – die deklarierten Elementtypen und Attribute mit einem Namensraum (dem sogenannten Zielnamensraum) verknüpfen. Die Elemente und Attribute des Namensraums können dann im XML-Dokument mit einem Präfix verwendet werden. Zusätzlich zur Namensraum-Deklaration enthält das XML-Dokument dann eine Angabe (URL) für den XML-Parser, wo das Schemadokument zu finden ist, welches die Elementtypen und Attribute des Namensraums definiert. Validierende Parser können so das XML-Schema laden, um das XML-Dokument auf Gültigkeit zu prüfen.

Weblinks

  • Namespaces in XML (deutsche Übersetzung
    Übersetzung der Empfehlung des World Wide Web Consortiums (W3C) zu XML-Namensräumen
  • W3C: Namespaces in XML – Empfehlung des World Wide Web Consortiums (W3C) zu XML-Namensräumen
  • rpbourret.com: XML Namespaces FAQ von Ronald Bourret – sehr umfangreich und detailliert!