XML: Die Sache mit den Namespaces

XML: Die Sache mit den Namespaces

XML: Die Sache mit den Namespaces

➪ Namespaces helfen bei der Klarstellung gemeinsam genutzter Fachbegriffe in einem Kontext. Insbesondere geht es darum, im Fall möglicher Mehrdeutigkeiten begriffliche Kollisionen und damit Fehlinterpretationen zu vermeiden.

Wir Menschen denken in Namen und Begriffen, hinter denen sich häufig komplexe Zusammenhänge verbergen. Teil dieser Komplexität sind andere Namen, andere Begriffe, die in jenem Kontext ebenfalls eine Rolle spielen und mit anderen Namen in Beziehung stehen. Indem Sie also einen bestimmten Begriff verwenden, schwingt eine ganze Wolke ergänzender Worte, Bilder, Wertungen im Hintergrund mit.

Die Begriffswolke stellt einen Namensraum dar. Der Namensraum bildet komplexe Zusammenhänge ab.

Dabei kann derselbe Begriff für eine ganze Anzahl grundverschiedener Komplexitäten bzw. Namensräume in Anspruch genommen werden. Ein einfaches Beispiel ist das Wort "Bruch", hinter dem sich mehrere mögliche Bedeutungen verbergen kann: Knochenbruch, Steinbruch, mathematischer Bruch. Es ist also notwendig, genauer zu sagen, in welchem Zusammenhang der Name verwendet wird.

Aber auch dann, wenn es um dieselbe Sache geht, kann es vorkommen, dass Sie deren Komplexität unterschiedlich wahrnehmen. Ein Grund dafür dürfte die allzu menschliche Neigung sein, individuelle Schwerpunkte zu setzen, einiges herausfiltern, zu ignorieren, anderes dafür verstärkt wahrzunehmen. Jeder sieht dasselbe Beziehungsgeflecht aller Dinge durch die eigene Brille, die die Wahrnehmung individuell einfärbt, dadurch kommen ununterbrochen Gegensätze in die Welt.

Ein weiterer Grund ist vermutlich der unterschiedliche Grad des Vorverständnisses. Je geringer die Kenntnis der Komplexität, desto geringer der Bezug zu den anderen Begrifflichkeiten, desto weniger können Sie vermutlich mit dem Einzelbegriff anfangen (bis hin zu "das sagt mir nichts"). Eine hundertprozentige Kenntnis der Zusammenhänge mag ein erstrebenswertes Ideal sein, realistisch ist es kaum.

Aber die Welt bleibt nicht stehen, die Dinge entwickeln sich weiter. Irgendwann passt der bisherige Namensraum nicht mehr, zusätzliche Namen kommen hinzu, die Bedeutung vorher vielleicht nebulös oder vage formulierter Begriffe wird konkretisiert.

Namensräume bleiben keineswegs statisch, unveränderlich, sondern sind vielmehr flexibel, dynamisch. Zur präzisen Verwendung eines Namens gehört, dass Sie nicht nur den dazugehörigen Namensraum kennen, sondern auch dessen Version.

Versionsabhängige Präzision

Um zusammenarbeiten zu können, ist eine verbindliche Definition einzelner Namen/Begrifflichkeiten unverzichtbar. Ändert sich diese Festlegung, so ist das eine Neu-Versionierung.

Hinter Namespaces stehen häufig komplexe Denkräume, angefüllt mit Wolken von Einzelbegriffen, die präzise definiert werden müssen, um praktisch verwendet werden zu können. Dabei geht es auch um Abgrenzungen, gegenseitige Abhängigkeiten, Annahmen, Voraussetzungen, versionsbedingte Erweiterungen.

Beispiele für klärungsbedürftige Mehrdeutigkeiten finden Sie bereits im XML-Kontext. Hier hat beispielsweise das Wort "Element" unterschiedliche Bedeutungen, hinter denen sich diverse zulässige Attribute und Childnodes verbergen. In XSLT dient als Element-Konstruktor. In XML-Schema stellt xs:element eine Definition dar, die es erlaubt, XML-Elemente zu definieren, zu referenzieren und ggf. zu validieren.

Begriffliche Klarstellungen sind eine wichtige Voraussetzung für effiziente Zusammenarbeit. Nebulöse Begriffe entpuppen sich dagegen oft als Fata Morgana und werden zur Quelle von Frust, wenn Beteiligte unter demselben Wort etwas anderes verstehen.

Diese Betrachtungen verdeutlichen die Notwendigkeit präziser Namespaces. Sobald ein Name von unterschiedlichen Namespaces (nur versionsbezogene oder thematisch grundverschiedene Differenzen) in Anspruch genommen werden könnte, ist eine exakte Definition zwingend erfoderlich.

Versionsbezogene Namespace-Deklarationen kommen nicht selten aus der objektorientierten Programmierung, speziell aus der XML-basierten Objektserialisierung. Beachten Sie hierzu meine Anmerkungen zu Objekt-Serialisierung mit C#.NET sowie JAXB.

Namespaces in XML

Grundsätzlich ist ein Namespace eine Zeichenkette, die weltweit einmalig sein sollte. Diese weltweite Einmaligkeit lässt sich am einfachsten durch Webadressen herstellen, zumal damit die Chance besteht, in der Linkadresse Informationen über die Problemstellung, Versionsunterschiede etc. bereitzustellen. Für den XML-Namespace ist jedoch nicht entscheidend, ob hinter der Namespace-Zeichenkette auch eine reale Webadresse liegt.

Ein Beispiel für einen Default-Namespace ist:


<?xml version="1.0" encoding="UTF-8"?>
<Bruch 
   xmlns="www.diese-Webadresse-existiert-nicht.de/math-Bruch">
   <Zaehler>57</Zaehler>
   <Nenner>95</Nenner>
</Bruch>

Neben Default-Namespaces können auch Namespace-Präfixe definiert werden; einzelne Elemente/Attribute können dann leichter zugeordnet werden.


<?xml version="1.0" encoding="UTF-8"?>
<abc:Bruch xmlns:abc="http://www.math.de" 
      xmlns:s="http://www.Steinbruch.de" 
      xmlns:w="http://www.Wortbruch.de" 
      xmlns:k="http://www.Knochenbruch.de">
   <abc:Zaehler>57</abc:Zaehler>
   <abc:Nenner>95</abc:Nenner>
</abc:Bruch>

XML: Namespace-definierte Struktur

Es ist auch möglich, Namespaces zu verwenden, um alternative Datenstrukturen zu definieren. Mit der Folge, dass es innerhalb eines Elements (scheinbar) identische Attributnamen geben kann, wenn man die Attributschreibweise wählt.


<ROOT xmlns:o="Ort" xmlns:m="Mensch">
  <element o:id="1" o:name="Neustadt" m:id="4" 
    m:name="Nixlos" m:vorname="Nicole" 
    m:Gehalt="1234.56" m:idOrt="1" />
  <element o:id="1" o:name="Neustadt" m:id="9" 
    m:name="Sprachlos" m:vorname="Stefan" 
    m:Gehalt="5430" m:idOrt="1" />
  <element o:id="3" o:name="Kapstadt" m:id="5" 
    m:name="Witzlos" m:vorname="Willi" 
    m:Gehalt="6789" m:idOrt="3" />
  <element o:id="3" o:name="Kapstadt" m:id="6" 
    m:name="Bodenlos" m:vorname="Betty" 
    m:Gehalt="3450" m:idOrt="3" />
</ROOT>

Diesen Ansatz erhalten Sie aus einem entsprechend strukturierten XML-Dokument durch folgendes XSL-Stylesheet:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:o="Ort" xmlns:m="Mensch">
  <xsl:output method="xml" indent="yes" />
  <xsl:template name="generateTree">
    <xsl:for-each select="//Mensch[Gehalt &amp;gt; 1000]">
      <element>
        <xsl:for-each select="../child::*[name()!='Mensch']">
          <xsl:attribute name="o:{local-name()}">
          <xsl:value-of select="." />
        </xsl:attribute>
        </xsl:for-each>
        <xsl:for-each select="./child::*[name()!='Kauf']">
          <xsl:attribute name="m:{local-name()}">
          <xsl:value-of select="." />
        </xsl:attribute>
        </xsl:for-each>
      </element>
    </xsl:for-each>
  </xsl:template>
  <xsl:template match="/">
    <ROOT>
      <xsl:call-template name="generateTree" />
    </ROOT>
  </xsl:template>
</xsl:stylesheet>

Umgekehrt lässt sich dieses Namespace-lastige XML-Dokument wieder auswerten und dabei aus Namespaces wieder Elemente zaubern:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:o="Ort" xmlns:m="Mensch">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
 <ROOT>
  <xsl:for-each select="$vtmp/element">
   <xsl:variable name="vcurelement" select="." />
   <INFO>
    <xsl:for-each
     select="namespace::*
        [. != 'http://www.w3.org/XML/1998/namespace']">
      <xsl:variable name="vtmpns">
        <xsl:value-of select="." />
      </xsl:variable>
      <xsl:element name="{$vtmpns}">
       <xsl:for-each
        select="$vcurelement/attribute::*
                         [namespace-uri() = $vtmpns]">
         <xsl:element name="{local-name()}">
          <xsl:value-of select="." />
         </xsl:element>
       </xsl:for-each>
      </xsl:element>
    </xsl:for-each>
   </INFO>
  </xsl:for-each>      
 </ROOT>
</xsl:template>
</xsl:stylesheet>

Das Ergebnis sieht dann wie folgt aus:


<ROOT xmlns:o="Ort" xmlns:m="Mensch">
  <INFO>
    <Ort>
      <id>1</id>
      <name>Neustadt</name>
    </Ort>
    <Mensch>
      <id>4</id>
      <name>Nixlos</name>
      <vorname>Nicole</vorname>
      <Gehalt>1234.56</Gehalt>
      <idOrt>1</idOrt>
    </Mensch>
  </INFO>
  <INFO>
    <Ort>
      <id>1</id>
      <name>Neustadt</name>
    </Ort>
    <Mensch>
      <id>9</id>
      <name>Sprachlos</name>
      <vorname>Stefan</vorname>
      <Gehalt>5430</Gehalt>
      <idOrt>1</idOrt>
    </Mensch>
  </INFO>
  <INFO>
    <Ort>
      <id>3</id>
      <name>Kapstadt</name>
    </Ort>
    <Mensch>
      <id>5</id>
      <name>Witzlos</name>
      <vorname>Willi</vorname>
      <Gehalt>6789</Gehalt>
      <idOrt>3</idOrt>
    </Mensch>
  </INFO>
  <INFO>
    <Ort>
      <id>3</id>
      <name>Kapstadt</name>
    </Ort>
    <Mensch>
      <id>6</id>
      <name>Bodenlos</name>
      <vorname>Betty</vorname>
      <Gehalt>3450</Gehalt>
      <idOrt>3</idOrt>
    </Mensch>
  </INFO>
</ROOT>

Als segensreich erweisen sich Namespaces bei der Programmierung, wenn Funktionaliäten unterschiedlicher Bereiche zusammenkommen. Stellen Sie sich vor, in einem XML-Input-Dokument stehen Informationen, die mittels zunächst gruppiert werden müssen, um die Ergebnisse bildlich in einer svg-Datei (Skalierbare Vektorgrafik) darzustellen, die schließlich als fo:instream-foreign-object in ein PDF-Dokument eingebettet werden soll. Obendrein sollen die Datentypen der Input-Informationen mittels XML-Schema gecastet werden. In einem solchen Ansatz kommen schnell mehrere Namespaces zusammen, und da ist ein klarer Überblick über die Zusammenhänge hilfreich:


<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:svg="http://www.w3.org/2000/svg">
</xsl:stylesheet>

wg / 12. April 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/namespaces.html