Home
Über mich
Blog
Veröffentlichungen
IT-Trainings
Impressum


XML Input Dokumente mit Namespaces

Namespaces im XML Input können erhöhte Anforderungen an die Folgeprogrammierung bewirken:

<ns1:Orte 
  xmlns="www.wilfried-grupe.de/Beispiele/2017"
  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>

Denn um Namespace-basierte Werte im XML Input eindeutig adressieren zu können, muss das XPath-Statement auch die Namespace-Prefixe 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.

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  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">
  <xsl:template match="/">
    <ergebnis>
      <xsl:value-of 
      select="/ns1:Orte/ns2:Ort[1]/ns3:Mensch[1]/ns4:Kauf[6]/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 die Namespaces, nicht aber die grundlegende Struktur der Daten geändert hat, so wird die Transformation der Input-Daten mit einiger Wahrscheinlichkeit komplett ins Leere laufen.

Wie so etwas passieren kann? Zahlreiche Datenlieferanten behaupten mit Recht, ihre Aufgabe sei es, Daten bereit zu stellen: was die Datenkonsumenten damit anfangen, liege nicht in ihrem Einflußbereich. 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 aus irgendeinem Grund 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 "zufällig" auffällt, daß entscheidungsrelevante Daten fehlen. Die Verzögerung in der Anpassung der Stylesheets kann ein erhebliches Schadenrisiko bergen. Eine automatisierte Warnmeldung, daß die Namespaces des XML Input Dokuments sich geändert haben, schafft hier nur geringe Abhilfe, denn die Anpassung der Folgekonvertierung muß ja trotzdem vorgenommen werden (in der Regel unter hohem Zeitdruck). Trotz aller Eile bedeutet das eine Verzögerung mit Verlustpotenzial.

Etliche Datenkonsumenten suchen nach Wegen, dieses Risiko zu minimieren. Zumindest für den Fall, daß sich zwar die Namespaces, nicht aber die Datenstrukturen ändern, könnte man doch eine Konvertierungslogik verwenden, die den XML Input durch eine Konvertierungs-Vorstufe von allen Namespaces "befreit", um anschließend "normal" weiterarbeiten zu können.

Ich empfehle diesen Weg ausdrücklich NICHT, weil er das Risiko, daß sich die Datenstrukturen grundlegend ändern können und die Adressierbarkeit der Felder dadurch verlorengeht, komplett ausblendet. Wer so arbeitet, sollte zumindest durch eine exakte Validierung jener temporären XML-Strukturen, die von den störenden Namespaces "befreit" wurden, sicherstellen, daß die XPath-Adressierbarkeit der Datenfelder gewährleistet ist.

Syntaktisch korrekt, aber mit schlechterer Performance und programmtechnisch mühsam pflegbar 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]/bez" />

Ein alternativer Ansatz bietet die folgenden Templates, deren Verwendung ich ebenfalls NICHT empfehle. Sie werfen (scheinbar) sämtliche Namespaces und Präfixe raus und generieren ein Zwischendokument, das sich einfacher adressieren läßt. (Tatsächlich werden die Namespaces geändert und damit die Elemente umbenannt.)

Vorsicht jedoch bei Attributen. Wenn Attribute mit demselben local-name(), aber unterschiedlichen Namespaces, von eben diesen Namespaces befreit werden, dann haben zwei Attribute denselben Namen: das XML Dokument ist dann nicht wohlgeformt, 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>

Hatte ich erwähnt, daß 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.

qrpic/namespaces1.jpg

wg / 14. Oktober 2017




Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf (info10@wilfried-grupe.de).



Vielen Dank für Ihr Interesse an meiner Arbeit.


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

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