urvater Logo

XML - Validieren

Vertrauen ist gut Kontroller ist besser. Gerade beim Datenaustausch zwischen verschiedenen Programmen oder Servern ist die Kontrolle der Daten unverzichtlich. Dabei ist es irrelevant ob es sich um einen internen oder externen Datenaustausch handelt. Niemand kann sich sicher sein, dass die Daten in der XML auch dem entsprechen, was erwartet wird. Hier ein kleines Update bei der Software, die uns die XML Daten sendet und schon ist es passiert. Im besten Fall sind nur wenige Datensätze betroffen, alles hat gelacht und nach 5 Minuten ist es bereinigt. Im schlimmsten Fall muß man sich Stunden mit der Datenbereinigung beschäfftigen oder ein Backup einspielen und die Daten erneut verarbeiten.

Die Validierung der Daten vor der Verarbeitung ist unerläßlich!

Um hier mit einem Beispiel arbeiten zu können nutze ich eine erdachte Produktliste, die zwischen 2 Firmen ausgetauscht werden soll.

Übermittelt werden Produkt-ID, Produkt-Name, Preis, Warenbeschreibung

Als CSV würde dies ggf. so aussehen

1234;"Ware 1";30,15;Beschreibung der Ware 1
2345;"Ware 2";50,60;Beschreibung dieser Ware

Eine XML Datei könnte so aussehen

<?xml version="1.0" ?>
<Produkte>
    <Produkt>
        <ID>1234</ID>
        <Bezeichnung>Ware 1</Bezeichnung>
        <Preis>30,15</Preis>
        <Beschreibung>Beschreibung der Ware 1</Beschreibung>
    </Produkt>
    <Produkt>
        <ID>1234</ID>
        <Bezeichnung>Ware 2</Bezeichnung>
        <Preis>50,60</Preis>
        <Beschreibung>Beschreibung der Ware</Beschreibung>
    </Produkt>
</Produkte>

Dabei kann die Menge in der Datei eine unbestimmte Anzahl an Produkten sein.

Validierung der Dokumentenstruktur

Der große Vorteil einer XML Datei gegenüber einer CSV Datei besteht in der strukturierten Datenerfassung. Würde der Datenstrom kurzzeitig unterbrechen, würde am Ziel nicht der gesamte Inhalt der Datei ankommen. Bei einer CSV würde es erst auffallen, wenn ein Eintrag in die Datenbank scheiter, weil ein Pflichtfeld nicht gefüllt war. Wieviele Daten zu diesem Zeitpunkt schon in die Datenbank geschrieben wurde ist ersteinmal unklar.
Bei einer XML Datei würde schon das Öffnen der Datei einen Fehler verursachen, da mindestens das Wurzelelemten nicht geschlossen wurde, weil dieses nicht mehr übermittelt wurde.

Was passiert, wenn der Sender, aus welchen Gründen auch immer, eine weitere Spalte hinzufügt oder eine Spalte entfernt und dies nicht gerade am Ende eines Datensatzes passiert?
Bei einer CSV k&omml;nnte der Eintrag in die Dantenbank scheitern, wenn z. B. ein String in eine Int-Spalte geschrieben werden soll. Bei einer XML würde eine Validierung einen Fehler erzeugen, wenn dieses Feld nicht mindestens in einer DTD definiert wurde.

Würde man diese Daten sofort per Skript bei einer CSV Datei oder per XSL bei einer XML Datei ausgeben, wären auch hier bei der Ausgabe eklatante Unterschiede zu erkennen.

Die Validierung kann mittels DTD oder auch XML-Schema vorgenommen werden. Zumindest für die Validierung der Dokumentenstruktur spielt es keine Rolle ob dies mittels DTD oder XML-Schema geschieht. Da wir aber auch den Inhalt der Elemente prüfen müssen, empfehle ich XML-Schema zu nutzen. Gerade für das Verstehen ist zwar die DTD anfangs leichter zu begreifen aber für eine möglichst genaue Prüfung der Daten ist ein XML-Schema zu bevorzugen.
Die anfängliche Mehrarbeit lohnt sich auf jeden Fall.

Validierung der Daten

Für die Validierung eignen sich verschiedene Mittel. Java, C++ oder PHP sollten als Beispiele reichen. Für XML steht uns zusätzlich noch DTD oder XML-Schema zur Verfügung. Bei einer möglichst genauen Prüfung schlägt hier das Schema ganz klar eine DTD. Kann man in einer DTD mehr oder weniger nur prüfen ob ein Element Daten enthät kann man in einem Schema auch prüfen um welchen Datentyp es sich handelt bzw. ob der übermittelte Datentyp in diesem Element erlaubt ist. Dies erleichtert wesentlich eine spätere Weiterverarbeitung der Daten, da man sicher sein kann, dass ein Element vom Typ Int auch einen Wert vom Typ Int enthält.

Eine sehr einfache DTD zur Validierung der Beispiel XML
produkt.dtd

<!ELEMENT Produkte (Produkt)+>
<!ELEMENT Produkt (ID,Bezeichnung,Preis,Beschreibung)>
<!ELEMENT ID (#PCDATA)>
<!ELEMENT Bezeichnung (#PCDATA)>
<!ELEMENT Preis (#PCDATA)>
<!ELEMENT Beschreibung (#PCDATA)>    

Gegen diese DTD geprüft ist die XML valide.

Nun das ganze mit einem XML Schema
produkt.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
    <xsd:documentation xml:lang="DE">
        Produkt Schema für Example.com.
        Copyright 2001 Example.com. Alle Rechte vorbehalten.
    </xsd:documentation>
</xsd:annotation>

<xsd:element name="Produkte" type="ProdukteTyp"/>

<xsd:element name="ID" type="xsd:int"/>

<xsd:element name="Bezeichnung" type="xsd:string"/>

<xsd:element name="Preis" type="xsd:decimal"/>

<xsd:element name="Beschreibung" type="xsd:string"/>

<xsd:complexType name="ProdukteTyp">
    <xsd:sequence>
        <xsd:element name="Produkt" type="ProduktTyp" minOccurs="1" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ProduktTyp">
    <xsd:sequence>
        <xsd:element ref="ID" minOccurs="1" maxOccurs="1"/>
        <xsd:element ref="Bezeichnung" minOccurs="1" maxOccurs="1"/>
        <xsd:element ref="Preis" minOccurs="1" maxOccurs="1"/>
        <xsd:element ref="Beschreibung" minOccurs="1" maxOccurs="1"/>
    </xsd:sequence>
</xsd:complexType>
</xsd:schema>    

Jetzt fällt die Validierung negativ aus, da der Preis im deutschen Zahlenformat für Währungen angegeben wurde. Der Wert vom Typ decimal muß aber anstatt eines Kommas einen Punkt als Dezimalstellentrenner besitzen.
Dies ist ein sehr einfaches Beispiel. Mit XML Schema könnte man noch viel mehr im voraus validieren und sich am Ende viel Programmierarbeit sparen.