XML / XML: Die Sache mit den Namespaces / Namespaces in XML-Dokumenten

Namespaces in XML-Dokumenten

Namespaces in XML-Dokumenten

➪ Namespaces im XML-Input können erhöhte Anforderungen an die Folgeprogrammierung bewirken. Bei jeder Änderung der Namespaces müssen ggf. zahlreiche XSL-Stylesheets oder XQuery-Scripte angepasst werden. Geschieht das nicht zeitnah, ist Informationsverlust die wahrscheinliche Folge.

Auf dieser Seite:

<ns1:Orte 
  xmlns="www.wilfried-grupe.de/Beispiele/2018"
  xmlns:ns1="www.wilfried-grupe.de/Orte" 
  xmlns:ns2="www.wilfried-grupe.de/Ort" 
  xmlns:ns3="www.wilfried-grupe.de/Mensch" 
  xmlns:ns4="www.wilfried-grupe.de/Kauf">
  ...
</ns1:Orte>

Um Namespace-basierte Werte im XML-Input eindeutig adressieren zu können, muss das XPath-Statement auch die Namespace-Präfixe einbinden, z.B.:


/ns1:Orte/ns2:Ort[1]/ns3:Mensch[1]/ns4:Kauf[6]

Damit das funktioniert, müssen auch die Input-Namespaces in das XSL-Stylesheet mit eingearbeitet werden (auch der dort benannte Default-Namespace).


<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:ns1="www.wilfried-grupe.de/Orte/2018"
  xmlns:ns2="www.wilfried-grupe.de/Ort" 
  xmlns:ns3="www.wilfried-grupe.de/Mensch"
  xmlns:ns4="www.wilfried-grupe.de/Kauf"
  xmlns:ns5="www.wilfried-grupe.de/Beispiele/2018">
  <xsl:template match="/">
    <ergebnis>
      <xsl:value-of 
      select="/ns1:Orte
              /ns2:Ort[1]
              /ns3:Mensch[1]
              /ns4:Kauf[6]
              /ns5:bez" />
    </ergebnis>
  </xsl:template>
</xsl:stylesheet>

Sie können sich vorstellen, was passiert, wenn ein Datenlieferant von heute auf morgen die Namespaces ändert und der Datenkonsument aus irgendeinem Grunde davon nichts mitkriegt. Auch wenn sich nur der Namespace, nicht aber die grundlegende Struktur der Daten geändert hat, so wird die Transformation der Input-Daten mit einiger Wahrscheinlichkeit teilweise oder komplett ins Leere laufen.

Zahlreiche behaupten mit Recht, ihre Aufgabe sei es, Daten bereit zu stellen: was die Datenkonsumenten damit anfangen, liege nicht in ihrem Einflussbereich. Komplexe Datenstrukturen können sich nun einmal ändern, die aktuellen Versionen werden jeweils in klar definierten Namespaces jedem XML-Dokument mitgegeben. Mit der Änderung der Namespaces kann auch eine Änderung der Datenstrukturen verbunden sein.

So betrachtet, liegt die Veranwortung für die rechtzeitige Anpassung der Verarbeitungslogiken beim Datenkonsumenten. Und diese Anpassung kann durchaus umfangreich sein, sie kann einige Hundert Implementierungen betreffen, die alle ihre Informationen aus derselben Datenquelle beziehen. Wenn also der Datenkonsument die Anpassung der Verarbeitungslogik nicht rechtzeitig vornimmt, dann wird er von den Änderungen "kalt erwischt". Es droht ein umfangreicher Datenverlust für die Folgeprozesse.

Es kann ziemlich lange dauern, bis irgendjemandem auffällt, dass entscheidungsrelevante Daten fehlen. Die Verzögerung in der Anpassung der Stylesheets kann ein erhebliches Schadenrisiko bergen. Eine automatisierte Warnmeldung, dass die Namespaces des XML-Input-Dokuments sich geändert haben, weist zwar auf den akuten Korrekturbedarf hin, schafft jedoch nur bedingte Abhilfe, denn die Anpassung der Folgekonvertierung muss ja trotzdem vorgenommen werden (in der Regel unter hohem Zeitdruck).

Kein guter Rat

Etliche Datenkonsumenten suchen nach Wegen, dieses Risiko zu umgehen. Zumindest für den Fall, dass sich zwar die Namespaces, nicht aber die Datenstrukturen ändern, könnte man doch eine Konvertierungslogik verwenden, die sämtliche Namespaces ignoriert.

Der Kniff liegt in der pragmatischen Anwendung der -Funktion. Ich empfehle diesen Weg ausdrücklich NICHT, weil er das Risiko, dass sich die Datenstrukturen grundlegend ändern können und die Adressierbarkeit der Felder dadurch verloren geht, komplett ausblendet.

Wer so arbeitet, sollte zumindest durch eine exakte jener temporären XML-Strukturen, die von den störenden Namespaces "befreit" wurden, sicherstellen, dass die XPath-Adressierbarkeit der Datenfelder gewährleistet ist. Notwendig ist in jedem Fall auch ein gründliches Testing der Konvertierungslogik.

Syntaktisch korrekt, aber mit schlechterer Performance und programmtechnisch mühsam wartbar könnte das Ganze so aussehen:


<xsl:value-of 
  select="/child::*[local-name()='Orte']
          /child::*[local-name()='Ort'][1]
          /child::*[local-name()='Mensch'][1]
          /child::*[local-name()='Kauf'][6]
          /child::*[local-name()='bez']/text()" />

Namespaces löschen?

Einen alternativen Ansatz bieten die folgenden Templates, deren Verwendung ich ebenfalls NICHT empfehle. In einer temporären Vorkonvertierung werden sämtliche Namespaces und Präfixe des Quelldokuments entfernt. Mit dem entstandenen Zwischendokument lässt sich wesentlich einfacher arbeiten, da die mühselige XPath-Adressierung der Namespaces entfällt.

Tatsächlich werden auf diese Weise die Namespaces nicht "rausgeworfen", sondern grundlegend geändert: Die Elemente werden faktisch umbenannt.

Zusätzliche Vorsicht ist bei Attributen geboten. Wenn Attribute mit demselben local-name(), aber unterschiedlichen Namespaces, von eben diesen Namespaces "befreit" werden, dann haben zwei Attribute nicht nur denselben Namen, sondern auch denselben Namespace: Das XML-Dokument ist dann nicht , und die Konvertierung wird auf einen Fehler laufen.


  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@* | node()" />
    </xsl:element>
  </xsl:template>
  <xsl:template match="@*">
    <xsl:attribute 
      name="{local-name()}">
        <xsl:value-of select="." />
      </xsl:attribute>
  </xsl:template>
  <xsl:template match="text()">
    <xsl:if test="normalize-space(.) !=''">
      <xsl:copy-of select="." />
    </xsl:if>
  </xsl:template>

Wie vorher, wird auch hier das Risiko ignoriert, dass sich die Datenstrukturen grundlegend ändern können und die Adressierbarkeit der Felder verloren geht. Hatte ich erwähnt, dass ich derlei Verfahren ausdrücklich NICHT empfehle?

Grundsätzlich bleibt der Datenkonsument in der Verantwortung, sich über Änderungen, die sich auf seine Geschäftsprozesse beziehen, auf dem Laufenden zu halten und rechtzeitig Vorsorge zu treffen.

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/namespaces1.html