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


Die XML-Namespace-Flut

In etlichen Unternehmen bzw. öffentlich-rechtlichen Institutionen haben wir es teilweise mit einer Namespace-Flut zu tun. Pro Jahr kommen Hunderte zusätzliche Namespaces hinzu.

Der Hintergrund ist häufig die Annotation-Verions-basierte Java-Objektserialisierung oder ihr Analogon aus C#.NET mit der attributorientierten Programmierung. Dahinter wiederum steht im Regelfall eine inhaltliche Aktualisierung, etwa aufgrund einer Gesetzesänderung, beispielsweise im Steuerrecht.

Hier taucht die Frage auf, wie wir mit permanenten Anpassungen umgehen können. Erschwerend kommt oft hinzu, sämtliche Namespaces individuell behandeln zu müssen: es ist dann oft nicht möglich, jeweils die aktuellste Version zu verwenden und frühere zu verwerfen.

Zur Einführung in diese Problematik folgt hier ein kurzes Beispiel.

<xs:schema 
	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
	xmlns:ns6="wg/201706" 
	elementFormDefault="qualified" 
	attributeFormDefault="unqualified">
  <xs:import namespace="wg/201706" 
	schemaLocation="elemente_name_201706.xsd"/>
  <xs:element name="Menschen">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Mensch" 
            maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Mensch">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ns6:vorname"/>
        <xs:element ref="ns6:nachname"/>        
        <xs:element ref="alter"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="alter"/>  
</xs:schema>

Das vorstehende XML Schema Dokument bindet das folgende XSD ein, in dem ein targetNamespace="wg/201706" definiert ist.

<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:ns1="wg/201706" 
  targetNamespace="wg/201706" 
  elementFormDefault="qualified" 
  attributeFormDefault="unqualified">
  <xs:simpleType name="stringmax20">
    <xs:restriction base="xs:string">
      <xs:pattern value="[A-Z][a-z]{1,19}"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="vorname" type="ns1:stringmax20"/>
  <xs:element name="nachname" type="ns1:stringmax20"/>
</xs:schema>

Die Auswertung von XML-Dokumenten ist nicht schwer, wenn es bei dieser Einbindung bleibt. Bald jedoch ändert oder erweitert sich das Haupt-Schema sowie das eingebundene XSD, da schließlich die Applikation veränderbar sein muß. Damit ändert sich auch die Struktur des XML Dokuments (wenn auch im einfachen Beispiel nur in Form der verwendeten Namespaces). Statt des ursprünglich alleinigen Namespaces "wg/201706" steht nun alternativ (oder zusätzlich) "wg/201707" im XML Dokument.

Wird die Folgeprogrammierung nicht angepaßt, so daß beide Namespaces flexibel und dennoch individuell behandelt werden können, droht Informationsverlust.

<xs:schema 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   elementFormDefault="qualified" 
   attributeFormDefault="unqualified"
xmlns:ns1="wg/201707"
targetNamespace="wg/201707">
<xs:simpleType name="stringmax20">
      <xs:restriction base="xs:string">
        <xs:pattern value="[A-Z][a-z]{1,19}"/>
      </xs:restriction>
    </xs:simpleType>
  <xs:element name="vorname" type="ns1:stringmax20"/>    
  <xs:element name="nachname" type="ns1:stringmax20"/>    
</xs:schema>

Wie gesagt, ist es hier keine Alternative, durch einen nicht empfohlenen "Kunstgriff" sämtliche Namespaces "rauszuwerfen" und anschließend alle Informationen einheitlich zu behandeln, was einen Informationsverlust nach sich ziehen kann.

Eine mögliche Lösung könnte darin bestehen, daß via xsl:choose der Namespace abgefragt und dann individuell behandelt wird, etwa direkt im for-each-Loop oder alternativ in Form einer Auslagerung in ein separates Template.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:ns6="wg/201706" 
  xmlns:ns7="wg/201707" 
  exclude-result-prefixes="ns6 ns7">
 <xsl:output method="xml" 
    exclude-result-prefixes="xs" indent="yes"/>
 <xsl:template match="/">
  <Personen>
   <xsl:for-each select="/Menschen/Mensch">
    <Person>
     <VN>
      <xsl:call-template name="vorname"/>
     </VN>
     <NN>
      <xsl:choose>
       <xsl:when test="ns6:nachname">
        <xsl:value-of select="ns6:nachname"/>
       </xsl:when>
       <xsl:when test="ns7:nachname">
        <xsl:value-of select="ns7:nachname"/>
       </xsl:when>
       <xsl:otherwise>UNBEKANNT</xsl:otherwise>
      </xsl:choose>
     </NN>     
    </Person>
   </xsl:for-each>
  </Personen>
 </xsl:template>
 <xsl:template name="vorname">
  <xsl:choose>
   <xsl:when test="ns6:vorname">
    <xsl:value-of select="ns6:vorname"/>
   </xsl:when>
   <xsl:when test="ns7:vorname">
    <xsl:value-of select="ns7:vorname"/>
   </xsl:when>
   <xsl:otherwise>UNBEKANNT</xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

qrpic/namespaces2.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