Wenn Sie schon einmal eine Enterprise-XML-API integriert und eine kryptische Ablehnung mit "element 'Quantity' is not valid in this context" erhalten haben, sind Sie bereits auf XSD gestoßen — auch wenn Sie es nicht namentlich kannten. XML Schema Definition (XSD) ist die Sprache, die exakt beschreibt, wie gültiges XML aussieht: welche Elemente erforderlich sind, welche Datentypen sie enthalten, wie oft sie vorkommen dürfen und welche Werte erlaubt sind. Dieser Leitfaden erklärt, wie Sie Schemas schreiben, dagegen validieren und die Fehler behandeln, denen Sie unweigerlich begegnen werden.
XSD wird durch die W3C XML Schema-Spezifikation definiert, die erstmals 2001 veröffentlicht wurde. Die Empfehlung XML Schema Part 2: Datatypes definiert das integrierte Typsystem. Es ist ausführlich und etwas kryptisch von Hand zu schreiben, aber extrem präzise — genau das, was Sie beim Austausch von Daten zwischen Systemen benötigen, die keine Mehrdeutigkeit tolerieren können.
Warum XML validieren?
- Datenfehler frühzeitig erkennen. Validierung an der API-Grenze bedeutet, dass ein fehlendes Pflichtfeld sofort mit einer klaren Fehlermeldung fehlschlägt — nicht 3 Schritte später, wenn Ihr Datenbank-Insert eine Constraint-Verletzung auslöst.
- Den Vertrag dokumentieren. Ein XSD-Schema ist ausführbare Dokumentation. Anders als ein Word-Dokument, das veraltet, ist ein Schema immer korrekt, weil das System es durchsetzt.
- Interoperabilität. In B2B-Integrationen — Rechnungsstellung, Auftragsverwaltung, Gesundheitswesen — validieren beide Parteien gegen ein gemeinsam veröffentlichtes Schema. Wenn es validiert, können beide Seiten es verarbeiten.
- Sicherheit. Validierung weist fehlerhafte Eingaben zurück, bevor sie die Geschäftslogik erreichen, und reduziert so die Angriffsfläche für XML-Injection-Angriffe.
Ein vollständiges XSD-Schema-Beispiel
Lassen Sie uns ein Schema für einen Produktkatalog erstellen. Dies deckt die am häufigsten verwendeten XSD-Funktionen ab — einfache Typen, komplexe Typen, Sequenzen, Attribute, Kardinalität und Datentypeinschränkungen:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Root element -->
<xs:element name="catalog">
<xs:complexType>
<xs:sequence>
<!-- One or more product elements -->
<xs:element name="product" type="ProductType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<!-- Product complex type -->
<xs:complexType name="ProductType">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="price" type="PriceType"/>
<xs:element name="stock" type="xs:nonNegativeInteger"/>
<xs:element name="categories" type="CategoriesType"/>
</xs:sequence>
<xs:attribute name="id" type="ProductIdType" use="required"/>
<xs:attribute name="status" type="ProductStatusType" use="optional" default="active"/>
</xs:complexType>
<!-- Price with currency attribute -->
<xs:complexType name="PriceType">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="CurrencyCodeType" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Categories — zero or more category strings -->
<xs:complexType name="CategoriesType">
<xs:sequence>
<xs:element name="category" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Product ID: alphanumeric, starts with P, 4-10 chars -->
<xs:simpleType name="ProductIdType">
<xs:restriction base="xs:string">
<xs:pattern value="P[A-Z0-9]{3,9}"/>
</xs:restriction>
</xs:simpleType>
<!-- Allowed product statuses -->
<xs:simpleType name="ProductStatusType">
<xs:restriction base="xs:string">
<xs:enumeration value="active"/>
<xs:enumeration value="discontinued"/>
<xs:enumeration value="out_of_stock"/>
</xs:restriction>
</xs:simpleType>
<!-- ISO 4217 currency codes — a subset -->
<xs:simpleType name="CurrencyCodeType">
<xs:restriction base="xs:string">
<xs:enumeration value="USD"/>
<xs:enumeration value="EUR"/>
<xs:enumeration value="GBP"/>
<xs:enumeration value="JPY"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>Viel zu verarbeiten. Lassen Sie uns die Schlüsselkonzepte durchgehen, bevor wir die Validierung in Aktion zeigen.
Wichtige XSD-Konzepte erklärt
- xs:element. Deklariert ein Element.
minOccursundmaxOccurssteuern die Kardinalität. Standardwert für beide ist 1. Verwenden SiemaxOccurs="unbounded"für unbegrenzte Wiederholung. - xs:complexType. Ein Element, das Kindelemente enthält oder Attribute hat. Einfache Elemente (nur Text) verwenden
xs:simpleTypeoder direkt einen eingebauten XSD-Typ. - xs:sequence. Kindelemente müssen in der definierten Reihenfolge erscheinen. Die Alternative ist
xs:all(beliebige Reihenfolge, jedes höchstens einmal) oderxs:choice(genau eines der aufgelisteten Elemente). - xs:attribute use="required". Macht das Attribut obligatorisch.
use="optional"(Standard) erlaubt sein Fehlen. Fügen Siedefault="value"für einen Standardwert bei Fehlen hinzu. - xs:restriction. Schränkt einen Basistyp ein. Gängige Facetten:
xs:pattern(Regex),xs:enumeration(erlaubte Werte),xs:minInclusive/xs:maxInclusive(numerische Grenzen),xs:minLength/xs:maxLength(Stringlänge). - xs:simpleContent + xs:extension. Die Methode, Attribute zu einem Element hinzuzufügen, das auch Textinhalt hat — wie im
PriceTypeoben, wo<price currency="USD">149.99</price>sowohl Text als auch ein Attribut hat.
Eingebaute XSD-Datentypen, die Sie tatsächlich verwenden werden
xs:string— beliebiger Textinhaltxs:integer— ganze Zahlen (positiv, negativ oder null)xs:nonNegativeInteger— ganze Zahlen ≥ 0 (gut für Mengen, Zählungen)xs:decimal— Dezimalzahl mit beliebiger Genauigkeit (gut für Preise)xs:boolean—trueoderfalse(akzeptiert auch1und0)xs:date— ISO 8601-Datum:2024-01-15xs:dateTime— ISO 8601-Datetime:2024-01-15T09:30:00Zxs:anyURI— eine URI/URLxs:base64Binary— Base64-kodierte Binärdaten
XML gegen ein XSD in Python validieren (lxml)
Pythons Standard-xml.etree.ElementTree unterstützt keine XSD-Validierung.
Dafür benötigen Sie lxml.
Die Abhängigkeit lohnt sich — lxmls Validierungsmeldungen sind detailliert und verweisen auf die genaue
Zeile, die das Problem verursacht:
pip install lxmlfrom lxml import etree
# Load the schema
with open('catalog.xsd', 'rb') as f:
schema_doc = etree.parse(f)
schema = etree.XMLSchema(schema_doc)
# Valid XML
valid_xml = """<?xml version="1.0"?>
<catalog version="1.0">
<product id="P0012" status="active">
<name>Mechanical Keyboard</name>
<price currency="USD">189.00</price>
<stock>42</stock>
<categories>
<category>Electronics</category>
<category>Peripherals</category>
</categories>
</product>
</catalog>"""
xml_doc = etree.fromstring(valid_xml.encode())
if schema.validate(xml_doc):
print("Valid!")
else:
for error in schema.error_log:
print(f"Error at line {error.line}: {error.message}")
# Invalid XML — missing required 'stock', bad product ID format
invalid_xml = """<?xml version="1.0"?>
<catalog version="1.0">
<product id="BADID">
<name>Test Product</name>
<price currency="USD">10.00</price>
<categories/>
</product>
</catalog>"""
invalid_doc = etree.fromstring(invalid_xml.encode())
schema.validate(invalid_doc)
for error in schema.error_log:
print(f"Line {error.line}: {error.message}")
# Line 3: Element 'product', attribute 'id': 'BADID' is not a valid value of the atomic type 'ProductIdType'.
# Line 7: Element 'categories': Missing child element(s). Expected is ( category ). ← if minOccurs > 0Validierung in Java — JAXP
Java hat eingebaute XSD-Validierung über die JAXP Validierungs-API (keine Drittanbieter-Bibliothek erforderlich). Dies ist das Muster, das in Enterprise-Java-Anwendungen und Spring Boot XML-Verarbeitung verwendet wird:
import javax.xml.XMLConstants;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import org.xml.sax.SAXException;
import java.io.IOException;
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new File("catalog.xsd"));
Validator validator = schema.newValidator();
try {
validator.validate(new StreamSource(new File("catalog.xml")));
System.out.println("Valid!");
} catch (SAXException e) {
System.out.println("Validation error: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO error: " + e.getMessage());
}XML Schema vs. JSON Schema
Wenn Sie JSON Schema verwendet haben, wird XSD vom Zweck her vertraut wirken, aber syntaktisch sehr anders sein. Ein kurzer Vergleich:
- Syntax. XSD ist XML; JSON Schema ist JSON. XSD ist ausführlicher, integriert sich aber natürlich in XML-Toolchains.
- Reife. XSD 1.0 existiert seit 2001 — Jahrzehnte an Werkzeugen, Validatoren und Bibliotheksunterstützung. JSON Schema entwickelt sich seit 2009 und hat erst in den letzten Jahren einen stabilen Entwurf erreicht.
- Typsystem. XSD hat ein reichhaltigeres eingebautes Typsystem:
xs:date,xs:decimal,xs:anyURIsind eingebaut. JSON Schema verlässt sich auf Format-Annotationen für Datumsangaben und URIs, die Validatoren möglicherweise durchsetzen oder auch nicht. - Namespace-Unterstützung. XSD unterstützt XML-Namespaces nativ. JSON Schema hat kein entsprechendes Konzept.
- Wann welches verwenden. Wenn Sie in einem XML-Ökosystem arbeiten, verwenden Sie XSD. Wenn Sie in einem JSON-Ökosystem arbeiten, verwenden Sie JSON Schema. Mischen Sie sie nicht.
Häufige Validierungsfehler und wie man sie behebt
- "Element X is not expected." Das Element erscheint in einer
xs:sequenceaußer der Reihenfolge oder ist überhaupt nicht im Schema definiert. Prüfen Sie den Elementnamen und seine Position relativ zu Geschwisterelementen. - "The value Y of attribute Z is not valid." Der Attributwert stimmt nicht mit seinem Typ oder seiner Enumeration überein. Häufig bei Statusfeldern und Währungscodes mit Tippfehlern.
- "Missing child element(s)." Ein erforderliches Kindelement (minOccurs > 0) fehlt. Prüfen Sie im Schema, welche Elemente unter dem übergeordneten Element obligatorisch sind.
- "Not a valid value of the atomic type." Eine einfache Typeinschränkung ist fehlgeschlagen — Muster, Bereich oder Enumeration. Prüfen Sie das Schema auf die
xs:restrictiondieses Typs. - "Content model is not determinist." Mehrdeutiges Schema — der Validator kann nicht bestimmen, welcher Zweig gilt. Wird normalerweise durch zwei Optionen mit demselben Tag-Namen in einem
xs:choiceverursacht.
Verwandte Tools
Arbeiten Sie mit XML-Schemas? Diese Tools helfen: XML-Validator für schnelle Wohlgeformtheitsprüfungen, XML-Formatierer um dichte XML vor dem Debugging lesbar zu machen, XML-Schema-Generator um automatisch ein XSD aus einem XML-Beispieldokument zu generieren, und XML zu JSON wenn Sie lieber mit JSON Schema arbeiten möchten.
Fazit
XSD ist ausführlich, aber es ist das richtige Werkzeug zur Definition strenger XML-Verträge in Enterprise-
und B2B-Kontexten. Die wichtigsten Muster zum Merken: Verwenden Sie xs:sequence mit
minOccurs/maxOccurs zur Strukturkontrolle, verwenden Sie xs:restriction
mit xs:enumeration und xs:pattern für Werteinschränkungen, und verwenden Sie
lxml in Python zur Validierung mit klaren Fehlermeldungen. Sobald Sie ein funktionierendes
Schema haben, wird es zur einzigen Wahrheitsquelle, auf die sich beide Seiten einer Integration beziehen können —
was viele Runden von Debugging hin und her erspart.