1. Wozu dient die XML-Validierung
XML ist ein sehr flexibles Format, manchmal sogar zu flexibel. Im Gegensatz zu streng typisierten Daten "verzeiht" XML Fehler, und wenn du vergisst, einen Tag zu schließen, oder jemand schreibt den falschen Attributnamen, kann das Programm beim Parsen einen Fehler auswerfen… oder das Problem gar nicht bemerken, was schlimmer ist.
Validierung gegen XSD (XML Schema Definition) — das ist eine Möglichkeit sicherzustellen, dass deine XML-Datei vollständig einem vorher definierten Vertrag entspricht: wie die Tags heißen, in welcher Reihenfolge sie stehen, welche Typen sie haben, ob sie verpflichtend sind und wie viele es geben kann. Das ist wie ein Passkontrolle für deine Daten — das Schema sagt: "Ohne dieses Feld oder wenn das Feld nicht die richtige Länge hat, kommst du hier nicht rein!"
Validierung ist wichtig in Unternehmenssystemen, beim Datenaustausch zwischen verschiedenen Systemen, APIs — überall dort, wo man kein "stilles" Akzeptieren fehlerhafter Strukturen haben möchte.
XSD (XML Schema Definition) — das ist ein separates XML-Dokument, das die Struktur eines anderen XML formalisiert. In einem XSD beschreibst du: welche Tags erlaubt sind, welche verpflichtend sind, welche Typen Attribute oder verschachtelte Elemente haben, Muster für Strings, Einschränkungen für Zahlen, sogar mögliche Werte (durch Constraints und Enumeration).
| XML | XSD (Strukturbeschreibung) |
|---|---|
|
|
|
|
XSD ist im Grunde ähnlich wie JSON Schema in der JSON-Welt.
2. Beispiel für XSD und zugehöriges XML
Beispiel XML
<person age="23">
<name>Ivan</name>
<email>ivan@example.com</email>
</person>
Beispiel XSD
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="email" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="age" type="xs:positiveInteger" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
Was dieses Schema beschreibt:
- Wurzelelement — <person>.
- Innerhalb von <person> müssen die Elemente <name> (verpflichtend) und <email> (optional) auftauchen.
- <person> muss ein Attribut age mit einem positiven ganzzahligen Wert haben.
3. XML-Validierung mit XSD in .NET
In .NET ist der klassische Weg, die Namespaces System.Xml und System.Xml.Schema zu nutzen.
Ablauf:
- XML-Datei laden
- XSD-Schema laden
- Das Schema an die XML-Validierung "anhängen"
- Den Validierungsprozess starten und mögliche Fehler behandeln
Hier ein einfaches Beispiel:
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
// 1. Fehler-Handler für die Validierung
void ValidationCallBack(object? sender, ValidationEventArgs e)
{
Console.WriteLine($"Validierungsfehler: {e.Message}");
}
string xmlPath = "person.xml";
string xsdPath = "person.xsd";
// 2. Schema laden
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", xsdPath);
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas = schemas;
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += ValidationCallBack;
// 3. XML mit den Einstellungen öffnen
using XmlReader reader = XmlReader.Create(xmlPath, settings);
while (reader.Read())
{
// Wir gehen einfach durchs Dokument - die Validierung passiert "on the fly"
}
Console.WriteLine("Validierung abgeschlossen!");
Erläuterungen:
- Alle Validierungsfehler werden im Callback ValidationCallBack aufgefangen.
- Wenn es keine Fehler gibt — entspricht das Dokument dem Schema (ValidationType.Schema).
- Bei Inkonsistenzen (fehlt age, ungültige email, zusätzliches Feld etc.) erscheinen entsprechende Meldungen in der Konsole.
Verschiedene Fehlertypen und Feedback
Die XSD-Validierung kann aus verschiedenen Gründen "meckern". Hier die häufigsten Szenarien und Beispiele für Fehler:
- Ein verpflichtendes Element fehlt (standardmäßig minOccurs="1").
- Ein überflüssiger Tag, der im XSD nicht beschrieben ist.
- Attribut hat den falschen Typ (age="abc" statt einer Zahl).
- Strings entsprechen nicht dem Pattern (definiert mit <xs:pattern>).
Typischer Fehler:
Validierungsfehler: Das Element 'age' mit dem Textinhalt 'abc' ist ungültig. Ein Wert vom Typ 'xs:positiveInteger' wurde erwartet.
4. Komplexere XSD-Schemata: Typen, Enumerations, Pattern
XSD ist quasi eine Sprache zum Beschreiben zulässiger Daten. Hier ein paar fortgeschrittene Beispiele:
Aufzählung zulässiger Werte
<xs:element name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="male"/>
<xs:enumeration value="female"/>
<xs:enumeration value="diverse"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Begrenzung der String-Länge
<xs:element name="code">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Pattern für email (vereinfacht)
<xs:element name="email">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="\w+@\w+\.\w+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Man kann eigene Typen definieren, davon erben, verschachtelte Elemente verwenden — praktisch wie in OOP!
5. Validierung eines komplexen Dokuments
Angenommen, unsere Lernanwendung exportiert jetzt eine Liste von Studenten als XML. Zeit für mehr Code!
Beispiel XML
<students>
<student id="1">
<name>Elena</name>
<grade>5</grade>
</student>
<student id="2">
<name>Alexey</name>
<grade>4</grade>
</student>
</students>
XSD-Schema
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element name="student" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="grade">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Validierung im Code (gleiche Vorgehensweise):
// Pfade zu den Dateien
string xmlPath = "students.xml";
string xsdPath = "students.xsd";
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", xsdPath);
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas = schemas;
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += ValidationCallBack;
using XmlReader reader = XmlReader.Create(xmlPath, settings);
while (reader.Read()) { /* wie zuvor */ }
6. Nützliche Hinweise
Wie man das Schema direkt im XML angibt (xsi:schemaLocation)
In der Praxis trifft man häufig XML-Dateien, in denen im Wurzelelement Attribute xsi:schemaLocation oder xsi:noNamespaceSchemaLocation stehen:
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="students.xsd">
...
</students>
Das validiert die Datei nicht automatisch, hilft aber manchen Validatoren und Editoren, das Schema zum Prüfen zu finden. Für die .NET-Validierung ist das nicht zwingend erforderlich, aber formal korrekt.
Validierung "on the fly" und im Speicher — mit XDocument
Wenn du mit LINQ to XML (XDocument) arbeitest, kannst du das XML-Dokument auch im Speicher validieren, ohne Dateien zu benutzen:
using System.Xml.Linq;
using System.Xml.Schema;
// Schema laden
XmlSchemaSet schema = new XmlSchemaSet();
schema.Add("", "students.xsd");
// XML in den Speicher laden
XDocument doc = XDocument.Load("students.xml");
// Validierung
doc.Validate(schema,
(o, e) => Console.WriteLine($"Fehler: {e.Message}"),
true // Warnungen mit prüfen (oft überflüssig)
);
Dieser Ansatz ist praktisch, wenn du XML programmatisch erzeugst oder änderst und sicherstellen willst, dass du keinen XML-Monster erzeugt hast, das das Schema verletzt.
7. Typische Fehler bei der XML-Validierung mit XSD
Fehler Nr. 1: Schema nicht eingebunden oder falscher Pfad zur XSD.
Als Ergebnis wird keine Validierung ausgeführt und die XML-Datei passiert die "Wache", selbst wenn sie Fehler enthält. Häufig wird ein relativer Pfad angegeben, aber die Anwendung sucht die Datei an einem unerwarteten Ort. Für Tests besser absolute Pfade verwenden oder das Schema neben die ausführbare Datei legen.
Fehler Nr. 2: Namespaces stimmen nicht überein (namespace).
Wenn dein Schema ein Namespace verwendet, musst du diesen als zweiten Parameter beim Hinzufügen des Schemas zu XmlSchemaSet.Add übergeben. Sonst schlägt die Validierung fehl, selbst wenn die XML-Struktur korrekt ist. Wenn es kein Namespace gibt — übergib eine leere Zeichenkette.
Fehler Nr. 3: Reihenfolge der Elemente stimmt nicht.
Wenn im Schema <xs:sequence> strikt definiert ist, dann ist die Reihenfolge der Elemente relevant. XML, in dem die richtigen Elemente in falscher Reihenfolge stehen, gilt als fehlerhaft.
Fehler Nr. 4: Im XML sind mehrere Namespaces angegeben.
Wenn das Dokument mehrere namespaces verwendet, kann das zu unerwarteten Validierungsproblemen führen. Die Unterstützung mehrerer Namespaces erfordert besondere Aufmerksamkeit und genaue Schema-Konfiguration.
Fehler Nr. 5: Keine Erfassung und Speicherung der Fehler.
Fehler einfach in die Konsole zu schreiben eignet sich für Debugging, aber nicht für eine produktive Anwendung. Besser ist, Fehler in einer Liste zu sammeln und dem Nutzer in einer brauchbaren Form zu übergeben — besonders bei Massenprüfungen (z. B. auf einem Webserver).
GO TO FULL VERSION