Kurumsal bir XML API'siyle entegrasyon yaptıysanız ve "element 'Quantity' is not valid in this context" gibi şifreli bir hata aldıysanız, adını bilmeden de olsa XSD ile tanışmış demeksiniz. XML Schema Definition (XSD), geçerli XML'in tam olarak nasıl görünmesi gerektiğini tanımlayan dildir: hangi öğelerin zorunlu olduğunu, hangi veri türlerini içerdiklerini, kaç kez görünebileceklerini ve hangi değerlere izin verildiğini belirtir. Bu rehber; şema yazımını, şemaya karşı doğrulamayı ve kaçınılmaz olarak karşılaşacağınız hataları nasıl ele alacağınızı anlatır.
XSD, 2001 yılında ilk kez yayımlanan W3C XML Şema spesifikasyonu tarafından tanımlanmaktadır. XML Schema Part 2: Datatypes tavsiyesi yerleşik tür sistemini tanımlar. Elle yazmak biraz zahmetli ve girift olabilir, ancak son derece hassastır — belirsizliğe tahammülü olmayan sistemler arasında veri alışverişi yaparken tam ihtiyacınız olan şey budur.
XML'i Neden Doğrulayalım?
- Veri hatalarını erken yakalayın. API sınırında doğrulama, eksik zorunlu bir alanın hemen açık bir hatayla başarısız olması anlamına gelir; veritabanı eklemeniz 3 adım sonra bir kısıtlama ihlali fırlatana kadar beklemenize gerek kalmaz.
- Sözleşmeyi belgeleyin. XSD şeması çalıştırılabilir belgedir. Eski hale gelen bir Word belgesinden farklı olarak şema, sistem onu zorunlu kıldığı için her zaman doğrudur.
- Birlikte çalışabilirlik. B2B entegrasyonlarında — faturalama, sipariş yönetimi, sağlık — her iki taraf da ortak yayımlanmış bir şemaya karşı doğrulama yapar. Doğrulanırsa her iki taraf da işleyebilir.
- Güvenlik. Doğrulama, hatalı biçimlendirilmiş girdiyi iş mantığına ulaşmadan reddeder ve XML enjeksiyon saldırıları için saldırı yüzeyini azaltır.
Eksiksiz Bir XSD Şema Örneği
Bir ürün kataloğu için şema oluşturalım. Bu örnek, en sık kullanılan XSD özelliklerini kapsar — basit türler, karmaşık türler, diziler, öznitelikler, kardinalite ve veri türü kısıtlamaları:
<?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>Sindirilecek çok şey var. Doğrulamayı uygulamada göstermeden önce temel kavramları inceleyelim.
Temel XSD Kavramları
- xs:element. Bir öğe bildirir.
minOccursvemaxOccurskardinaliteyi kontrol eder. Her ikisi için varsayılan değer 1'dir. Sınırsız tekrar içinmaxOccurs="unbounded"kullanın. - xs:complexType. Alt öğeler içeren veya öznitelikleri olan bir öğe. Basit öğeler (yalnızca metin) doğrudan
xs:simpleTypeveya yerleşik XSD türü kullanır. - xs:sequence. Alt öğeler tanımlanan sırada görünmelidir. Alternatif olarak
xs:all(herhangi bir sıra, her biri en fazla bir kez) veyaxs:choice(listelenen öğelerden tam olarak biri) kullanılabilir. - xs:attribute use="required". Özniteliği zorunlu yapar.
use="optional"(varsayılan) yokluğuna izin verir. Yokken varsayılan değer içindefault="value"ekleyin. - xs:restriction. Temel türü kısıtlar. Yaygın yönler:
xs:pattern(regex),xs:enumeration(izin verilen değerler),xs:minInclusive/xs:maxInclusive(sayısal sınırlar),xs:minLength/xs:maxLength(dize uzunluğu). - xs:simpleContent + xs:extension. Hem metin içeriğine hem de bir özniteliğe sahip öğelere öznitelik eklemenin yolu — yukarıdaki
PriceType'ta kullanıldığı gibi;<price currency="USD">149.99</price>hem metin hem de öznitelik içerir.
Gerçekten Kullanacağınız Yerleşik XSD Veri Türleri
xs:string— herhangi bir metin içeriğixs:integer— tam sayılar (pozitif, negatif veya sıfır)xs:nonNegativeInteger— ≥ 0 tam sayılar (miktarlar ve sayımlar için ideal)xs:decimal— isteğe bağlı hassasiyetli ondalık (fiyatlar için ideal)xs:boolean—trueveyafalse(1ve0'ı da kabul eder)xs:date— ISO 8601 tarihi:2024-01-15xs:dateTime— ISO 8601 tarih-saati:2024-01-15T09:30:00Zxs:anyURI— bir URI/URLxs:base64Binary— Base64 ile kodlanmış ikili veri
Python'da XML'i XSD'ye Göre Doğrulama (lxml)
Python'ın standart xml.etree.ElementTree modülü XSD doğrulamasını desteklemez.
Bunun için lxml'e ihtiyacınız var.
Bağımlılığa değer — lxml'in doğrulama mesajları ayrıntılıdır ve soruna yol açan tam satırı gösterir:
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 > 0Java'da Doğrulama — JAXP
Java, üçüncü taraf bir kütüphane gerekmeksizin JAXP doğrulama API'si aracılığıyla yerleşik XSD doğrulaması sunar. Bu, kurumsal Java uygulamalarında ve Spring Boot XML işlemede kullanılan kalıptır:
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 Şema ile JSON Şema Karşılaştırması
JSON Şema kullandıysanız, XSD amaç olarak tanıdık ama sözdizimi olarak çok farklı gelecektir. Hızlı bir karşılaştırma:
- Sözdizimi. XSD, XML'dir; JSON Şema ise JSON'dır. XSD daha ayrıntılıdır ancak XML araç zincirlerine doğal olarak entegre olur.
- Olgunluk. XSD 1.0, 2001'den beri var — onlarca yıllık araç desteği, doğrulayıcılar ve kütüphane desteği. JSON Şema 2009'dan beri gelişmekte ve yalnızca son yıllarda kararlı bir taslağa ulaştı.
- Tür sistemi. XSD daha zengin bir yerleşik tür sistemine sahiptir:
xs:date,xs:decimal,xs:anyURIyerleşiktir. JSON Şema, doğrulayıcıların uygulayıp uygulamayabileceği tarihler ve URI'lar için biçim ek açıklamalarına güvenir. - Ad alanı desteği. XSD, XML ad alanları için yerel desteğe sahiptir. JSON Şema'nın eşdeğer bir kavramı yoktur.
- Hangisini ne zaman kullanmalı. XML ekosisteminde çalışıyorsanız XSD kullanın. JSON ekosisteminde çalışıyorsanız JSON Şema kullanın. İkisini karıştırmayın.
Yaygın Doğrulama Hataları ve Çözümleri
- "Element X is not expected." Öğe bir
xs:sequence'de sıra dışında görünüyor ya da şemada hiç tanımlanmamış. Öğe adını ve kardeş öğelere göre konumunu kontrol edin. - "The value Y of attribute Z is not valid." Öznitelik değeri türüyle veya numaralandırmayla eşleşmiyor. Yazım hatası içeren durum alanları ve para birimi kodlarında yaygındır.
- "Missing child element(s)." Zorunlu bir alt öğe (minOccurs > 0) eksik. Üst öğe altında hangi öğelerin zorunlu olduğunu şemada kontrol edin.
- "Not a valid value of the atomic type." Basit tür kısıtlaması başarısız oldu — desen, aralık veya numaralandırma. O türdeki
xs:restriction'ı şemada kontrol edin. - "Content model is not determinist." Belirsiz şema — doğrulayıcı hangi dalın geçerli olduğunu belirleyemiyor. Genellikle bir
xs:choice'da aynı etiket adına sahip iki seçenekten kaynaklanır.
İlgili Araçlar
XML şemalarıyla mı çalışıyorsunuz? Bu araçlar işinize yarayacak: XML Validator hızlı biçimsellik kontrolleri için, XML Formatter hata ayıklamadan önce yoğun XML'i okunabilir hale getirmek için, XML Schema Generator örnek bir XML belgesinden otomatik olarak XSD oluşturmak için ve XML to JSON JSON Şema ile çalışmayı tercih ettiğinizde.
Özet
XSD ayrıntılıdır, ancak kurumsal ve B2B bağlamlarında katı XML sözleşmeleri tanımlamak için doğru araçtır.
Hatırlanması gereken temel kalıplar: yapıyı kontrol etmek için minOccurs/maxOccurs ile birlikte
xs:sequence kullanın, değer kısıtlamaları için xs:enumeration ve xs:pattern ile
birlikte xs:restriction kullanın ve net hata mesajlarıyla doğrulama için Python'da lxml kullanın.
Çalışan bir şemanız olduğunda, bir entegrasyonun her iki tarafının da başvurabileceği tek gerçek kaynağı haline gelir —
bu da çok sayıda ileri geri hata ayıklama sürecinden sizi kurtarır.