K čemu je schéma
Parser ověří, že je dokument dobře formovaný. Nepozná ale, jestli v objednávce nechybí zákazník nebo jestli je v ceně číslo. Tohle hlídá schéma. Když si dvě strany vyměňují data — e-shop a účetní systém, firma a úřad —, schéma slouží jako popis požadované struktury dat: povinných polí, jejich typů a pořadí. Úspěšná validace potvrzuje shodu s tímto schématem. Nezaručuje však přijetí dokumentu druhou stranou: aplikace může navíc kontrolovat součty, existenci zákazníka nebo oprávnění odesílatele.
XSD je doporučení W3C z roku 2001 (verze 1.0, druhé vydání 2004). Verze 1.1 z roku 2012
přidala například podmínky xs:assert, ale řada nástrojů včetně rozšířené knihovny
libxml2 podporuje jen XSD 1.0. Schéma je samo XML dokumentem v jmenném prostoru
http://www.w3.org/2001/XMLSchema, obvykle s prefixem xs: nebo
xsd:.
Příklad: objednávka a její schéma
Mějme jednoduchou objednávku:
<?xml version="1.0" encoding="UTF-8"?>
<objednavka cislo="2026-117">
<datum>2026-09-28</datum>
<zakaznik>Jana Nováková</zakaznik>
<polozka mnozstvi="2">
<nazev>Hrnek</nazev>
<cena mena="CZK">199.00</cena>
</polozka>
</objednavka> Schéma, které popisuje její strukturu:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="objednavka">
<xs:complexType>
<xs:sequence>
<xs:element name="datum" type="xs:date"/>
<xs:element name="zakaznik" type="xs:string"/>
<xs:element name="polozka" type="PolozkaTyp" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="cislo" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:complexType name="PolozkaTyp">
<xs:sequence>
<xs:element name="nazev" type="xs:string"/>
<xs:element name="cena" type="CenaTyp"/>
</xs:sequence>
<xs:attribute name="mnozstvi" type="xs:positiveInteger" default="1"/>
</xs:complexType>
<xs:complexType name="CenaTyp">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="mena" type="MenaTyp" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="MenaTyp">
<xs:restriction base="xs:string">
<xs:enumeration value="CZK"/>
<xs:enumeration value="EUR"/>
</xs:restriction>
</xs:simpleType>
</xs:schema> Co schéma říká:
- kořenem je
objednavkas povinným atributemcislo, - uvnitř jsou v tomto pořadí
datum(platné datum),zakaznika jedna nebo víc položek, - položka má název a cenu;
mnozstvije kladné celé číslo a pokud chybí, bere se 1, - cena je desetinné číslo s povinnou měnou, a to pouze CZK nebo EUR.
Jednoduché a komplexní typy
Jednoduchý typ (xs:simpleType) popisuje hodnotu bez vnořených
elementů a atributů — text, číslo, datum. Mají ho atributy a elementy, které obsahují jen text.
Komplexní typ (xs:complexType) popisuje element s potomky nebo
atributy. Element cena v příkladu je komplexní typ s jednoduchým obsahem:
obsahuje jen číslo, ale má atribut.
Nejpoužívanější vestavěné typy:
| Typ | Příklad hodnoty | Poznámka |
|---|---|---|
| xs:string | Jana Nováková | libovolný text |
| xs:integer | -42 | celé číslo bez omezení rozsahu |
| xs:positiveInteger | 3 | celé číslo větší než 0 |
| xs:decimal | 199.00 | desetinné číslo, oddělovač je vždy tečka |
| xs:boolean | true, false, 1, 0 | jiné hodnoty (ano/ne) neprojdou |
| xs:date | 2026-09-28 | formát RRRR-MM-DD |
| xs:dateTime | 2026-09-28T14:30:00+02:00 | datum a čas, volitelně s časovým pásmem |
| xs:anyURI | https://www.xml.cz/ | adresa URI |
Typy lze pojmenovat a použít opakovaně (PolozkaTyp), nebo je zapsat přímo uvnitř
elementu jako anonymní (typ elementu objednavka).
Pořadí a počet prvků
| Zápis | Význam |
|---|---|
| xs:sequence | potomci musí přijít přesně v uvedeném pořadí |
| xs:choice | použije se právě jedna z možností |
| xs:all | každý potomek nejvýš jednou, v libovolném pořadí |
| minOccurs / maxOccurs | kolikrát se prvek smí opakovat; výchozí je 1 a 1, "unbounded" = bez omezení |
| use="required" | atribut je povinný; bez něj je atribut nepovinný |
Omezení hodnot (facety)
Vestavěný typ lze zúžit pomocí xs:restriction. K dispozici jsou výčty hodnot
(xs:enumeration), regulární výrazy (xs:pattern), rozsahy
(xs:minInclusive, xs:maxExclusive…), délky
(xs:length, xs:maxLength) a počty číslic.
<xs:simpleType name="PscTyp">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{3} ?[0-9]{2}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="SlevaTyp">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
<xs:fractionDigits value="2"/>
</xs:restriction>
</xs:simpleType> Regulární výraz v xs:pattern vždy musí odpovídat celé hodnotě —
nepíše se ^ ani $. Syntaxe se v detailech liší od regulárních výrazů
v JavaScriptu nebo PHP.
Vestavěné typy shrnuje reference datových typů XSD, typy i komponenty schématu na jedné stránce tahák XML a JSON.
První schéma krok za krokem
Nejrychleji se XSD naučíš na vlastním příkladu. Napišme schéma pro seznam zaměstnanců, ve kterém hlídáme povinné údaje, délku jmen, formát rodného čísla, plat a povolené druhy úvazku.
<?xml version="1.0" encoding="UTF-8"?>
<zamestnanci>
<zamestnanec osobni-cislo="1042" uvazek="castecny">
<jmeno>Jana</jmeno>
<prijmeni>Nováková</prijmeni>
<rodne-cislo>905123/1234</rodne-cislo>
<email>jana.novakova@example.cz</email>
<plat>42500.00</plat>
</zamestnanec>
<zamestnanec osobni-cislo="1043">
<jmeno>Petr</jmeno>
<prijmeni>Svoboda</prijmeni>
<rodne-cislo>8807151234</rodne-cislo>
<telefon>+420 601 123 456</telefon>
<plat>38000</plat>
</zamestnanec>
</zamestnanci> 1. Kořenový element a opakování
Začni kořenem. zamestnanci obsahuje jeden nebo víc prvků
zamestnanec — maxOccurs="unbounded" povoluje libovolný počet,
minOccurs je ve výchozím stavu 1, takže prázdný seznam neprojde.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="zamestnanci">
<xs:complexType>
<xs:sequence>
<xs:element name="zamestnanec" type="Zamestnanec" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- sem přijdou typy z dalších kroků -->
</xs:schema> 2. Vlastní jednoduché typy s omezeními
Pro hodnoty s pravidly vytvoř pojmenované typy. Každý vychází z vestavěného typu a
xs:restriction ho zužuje: délkou, rozsahem, počtem desetinných míst, výčtem nebo
regulárním výrazem.
<!-- Rodné číslo: RRMMDD, u žen měsíc +50, od roku 2004 i +20/+70; lomítko nepovinné -->
<xs:simpleType name="RodneCislo">
<xs:restriction base="xs:string">
<xs:pattern value="\d{2}(0[1-9]|1[0-2]|2[1-9]|3[0-2]|5[1-9]|6[0-2]|7[1-9]|8[0-2])(0[1-9]|[12]\d|3[01])/?\d{3,4}"/>
</xs:restriction>
</xs:simpleType>
<!-- Jméno: 1 až 50 znaků, vícenásobné mezery se sloučí -->
<xs:simpleType name="Jmeno">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="50"/>
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
<!-- Plat: nezáporné číslo s nejvýš dvěma desetinnými místy -->
<xs:simpleType name="Plat">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:fractionDigits value="2"/>
</xs:restriction>
</xs:simpleType>
<!-- Úvazek: jen jedna z povolených hodnot -->
<xs:simpleType name="Uvazek">
<xs:restriction base="xs:string">
<xs:enumeration value="plny"/>
<xs:enumeration value="castecny"/>
<xs:enumeration value="dpp"/>
</xs:restriction>
</xs:simpleType> Rodné číslo a regulární výraz: vzor ověří tvar a rozumné hodnoty měsíce a dne,
ale ne dělitelnost jedenácti — tu XSD 1.0 spočítat neumí. Na takovou kontrolu je potřeba
xs:assert z XSD 1.1, Schematron, nebo kontrola v aplikaci. Stejně tak vzor
nepozná, že 31. února neexistuje.
3. Struktura záznamu: povinné a nepovinné prvky
Komplexní typ popíše, co zaměstnanec obsahuje. xs:sequence určuje pořadí,
minOccurs="0" dělá prvek nepovinným a maxOccurs="2" povoluje nejvýš
dva telefony. Atribut osobni-cislo je povinný (use="required"),
uvazek má výchozí hodnotu.
<xs:complexType name="Zamestnanec">
<xs:sequence>
<xs:element name="jmeno" type="Jmeno"/>
<xs:element name="prijmeni" type="Jmeno"/>
<xs:element name="rodne-cislo" type="RodneCislo"/>
<xs:element name="email" type="xs:string" minOccurs="0"/>
<xs:element name="telefon" type="xs:string" minOccurs="0" maxOccurs="2"/>
<xs:element name="plat" type="Plat"/>
</xs:sequence>
<xs:attribute name="osobni-cislo" type="xs:positiveInteger" use="required"/>
<xs:attribute name="uvazek" type="Uvazek" default="plny"/>
</xs:complexType> 4. Validace a čtení chyb
Hotové schéma vlož spolu s dokumentem do validátoru na záložku Schéma. Když
v dokumentu změníš úvazek na brigada, měsíc v rodném čísle na 13 a plat na
1500.555, validátor (libxml2) ohlásí, která omezení (facety) hodnota porušila:
Element 'zamestnanec', attribute 'uvazek': [facet 'enumeration'] The value 'brigada'
is not an element of the set {'plny', 'castecny', 'dpp'}.
Element 'rodne-cislo': [facet 'pattern'] The value '901323/1234' is not accepted by the pattern …
Element 'plat': [facet 'fractionDigits'] The value '1500.555' has more fractional digits
than are allowed ('2'). Když nechceš začínat od nuly, nech si ve validátoru schéma vygenerovat z ukázkového dokumentu a pak ho zpřísni o omezení podle tohoto postupu.
Jak dokument se schématem propojit a validovat
Dokument může na své schéma odkázat atributem ze jmenného prostoru
http://www.w3.org/2001/XMLSchema-instance. Pro dokument bez jmenného prostoru se
použije xsi:noNamespaceSchemaLocation, pro dokument ve jmenném prostoru
xsi:schemaLocation s dvojicí „URI prostoru a cesta ke schématu“.
<objednavka xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="objednavka.xsd"
cislo="2026-117">
…
</objednavka> Odkaz je jen nápověda: validátor ho může použít, ale v praxi aplikace většinou předává schéma sama. Z příkazové řádky se dokument ověří nástrojem xmllint:
xmllint --noout --schema objednavka.xsd objednavka.xml
Pokud schéma cílí na jmenný prostor (targetNamespace), musí v něm být i elementy
dokumentu. Téměř vždy se k tomu přidává elementFormDefault="qualified", aby do
jmenného prostoru patřily i vnořené elementy, ne jen kořen. Více o tom v kapitole
Jmenné prostory.
XSD, DTD, nebo něco jiného?
Starší DTD je jednodušší, ale nezná datové typy ani jmenné prostory. XSD je dnes standardem pro výměnu dat — používá ho například český formát elektronické faktury ISDOC i mnoho rozhraní státní správy. RELAX NG nabízí stručnější zápis (validátor ho umí ověřit stejně jako DTD) a Schematron doplňuje pravidla, která se v XSD 1.0 zapsat nedají (např. „datum splatnosti je po datu vystavení“).
Rozdělení schématu: include a import
<xs:include schemaLocation="typy.xsd"/>
<xs:import namespace="urn:adresy" schemaLocation="adresy.xsd"/> Include skládá schéma pro stejný cílový prostor, případně přebírá schéma bez targetNamespace. Import zpřístupňuje komponenty jiného prostoru, včetně prostoru bez názvu při vhodné deklaraci. schemaLocation uvádí, kde lze schéma hledat. O tom, které soubory se skutečně načtou, rozhoduje nastavení validátoru a jeho způsob vyhledávání souborů (resolver).
Názvy typů v odkazech jsou QName. Deklaruj jejich prefix a nezaměňuj jmenný prostor kontrolovaného XML dokumentu s namespace souboru schématu. Při načítání nedůvěryhodných schémat povol jen předem známé místní soubory.
Extension a restriction
<xs:complexType name="Zaklad">
<xs:sequence><xs:element name="jmeno" type="xs:string"/></xs:sequence>
</xs:complexType>
<xs:complexType name="Rozsireny">
<xs:complexContent><xs:extension base="Zaklad">
<xs:sequence><xs:element name="vek" type="xs:nonNegativeInteger"/></xs:sequence>
</xs:extension></xs:complexContent>
</xs:complexType> Extension zde za jméno přidá věk. Restriction omezuje povolené hodnoty nebo obsah; není to libovolná změna základního typu. Odvozený obsah musí splnit pravidla platného omezení. U jednoduchých typů jsou nejběžnější facety, například minInclusive a pattern.
Jedinečnost a vazby: key, unique, keyref
<xs:key name="polozkaId">
<xs:selector xpath="polozka"/>
<xs:field xpath="@id"/>
</xs:key>
<xs:keyref name="vazba" refer="polozkaId">
<xs:selector xpath="odkaz"/>
<xs:field xpath="@polozka"/>
</xs:keyref> Key vyžaduje úplný a jedinečný klíč, unique kontroluje jedinečnost přítomných úplných hodnot a keyref odkazuje na definovaný key nebo unique ve svém rozsahu. Selector a field používají omezenou syntaxi XPath, ne libovolný výraz XPath 3.1.
U instancí ve jmenném prostoru použij prefixy také v těchto cestách. XSD 1.1 nabízí další možnosti včetně assertions, které vyžadují procesor s podporou 1.1. Online XML.cz validátor není obecný XSD 1.1 procesor.
Úplný příklad key a keyref
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="katalog">
<xs:complexType><xs:sequence>
<xs:element name="kniha" maxOccurs="unbounded"><xs:complexType>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType></xs:element>
<xs:element name="vyber" minOccurs="0" maxOccurs="unbounded"><xs:complexType>
<xs:attribute name="ref" type="xs:string" use="required"/>
</xs:complexType></xs:element>
</xs:sequence></xs:complexType>
<xs:key name="knihaId"><xs:selector xpath="kniha"/><xs:field xpath="@id"/></xs:key>
<xs:keyref name="vybranaKniha" refer="knihaId"><xs:selector xpath="vyber"/><xs:field xpath="@ref"/></xs:keyref>
</xs:element>
</xs:schema> <katalog><kniha id="k1"/><kniha id="k2"/><vyber ref="k2"/></katalog> Spusť xmllint --noout --schema vazby.xsd vazby.xml nebo vlož oba soubory do záložky Schéma. Změna ref na k3 poruší keyref; změna druhého id na k1 poruší key. Identitní omezení mají rozsah v instanci elementu katalog. Nejsou univerzální databázový cizí klíč mezi libovolnými soubory.
Selector a field v XSD 1.0 používají omezenou XPath syntaxi, ne libovolné funkce XPath testeru. Pokud přidáš targetNamespace, potřebuješ odpovídající prefixy i v identitních cestách. Key vyžaduje přítomnou a jedinečnou hodnotu; unique dovoluje, aby vybraná hodnota chyběla. XSD 1.1 assertions jsou jiné pravidlo a vyžadují 1.1 procesor.
Spustitelný include a import: tři místní schémata
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:k="urn:knihy" xmlns:a="urn:adresy" targetNamespace="urn:knihy" elementFormDefault="qualified">
<xs:include schemaLocation="typy.xsd"/>
<xs:import namespace="urn:adresy" schemaLocation="adresy.xsd"/>
<xs:element name="kniha"><xs:complexType><xs:sequence>
<xs:element name="nazev" type="k:Nazev"/>
<xs:element ref="a:mesto"/>
</xs:sequence></xs:complexType></xs:element>
</xs:schema> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:knihy">
<xs:simpleType name="Nazev"><xs:restriction base="xs:string"><xs:minLength value="1"/></xs:restriction></xs:simpleType>
</xs:schema> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:adresy" elementFormDefault="qualified">
<xs:element name="mesto" type="xs:string"/>
</xs:schema> <kniha xmlns="urn:knihy" xmlns:a="urn:adresy"><nazev>XML</nazev><a:mesto>Praha</a:mesto></kniha> xmllint --nonet --noout --schema kniha.xsd kniha.xml Validní dokument projde. Prázdný nazev poruší minLength. Odebrání prefixu a u města jej přesune do urn:knihy a validace selže. Chybějící adresy.xsd je chyba načtení schématu, nikoli chyba města. Relativní schemaLocation se řeší vůči zdroji schématu; pokud soubor předáváš jako text, nastav také základní adresu schématu (base URI), vůči níž se odkazy vyhodnotí, nebo vlastní způsob načítání souborů. Účinek --nonet závisí na verzi a loaderu libxml2; zde se oba soubory načítají lokálně. Řízení externích zdrojů vysvětluje kapitola příkazové řádky.