XML Schema (XSD) Tutorial: From Basics to Advanced
A comprehensive guide to creating XML Schema definitions for validating XML documents.
What is XML Schema (XSD)?
XML Schema Definition (XSD) is a World Wide Web Consortium (W3C) recommendation that specifies how to formally describe the elements and structure of an XML document. Think of XSD as a blueprint or contract that defines what your XML data should look like.
XSD schemas are more powerful than DTDs (Document Type Definitions) because they:
- Support data types (strings, integers, dates, etc.)
- Are written in XML syntax
- Support namespaces
- Are extensible
- Allow for more precise validation rules
Basic XSD Structure
Every XSD document starts with a schema root element that declares the XML Schema namespace:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Schema definitions go here -->
</xs:schema>Simple Types
Simple types define elements that contain only text content (no child elements or attributes). XSD provides built-in simple types:
xs:string- Character stringsxs:integer- Whole numbersxs:decimal- Decimal numbersxs:boolean- true/false valuesxs:date- Date values (YYYY-MM-DD)xs:dateTime- Date and time values
<xs:element name="title" type="xs:string"/>
<xs:element name="price" type="xs:decimal"/>
<xs:element name="quantity" type="xs:integer"/>
<xs:element name="inStock" type="xs:boolean"/>Complex Types
Complex types define elements that contain other elements and/or attributes:
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>Element Ordering
XSD provides three ways to specify how child elements appear:
- sequence: Elements must appear in the specified order
- choice: Only one of the elements can appear
- all: Elements can appear in any order (each at most once)
Restrictions (Facets)
Restrictions allow you to limit the acceptable values for an element:
<!-- Restrict string length -->
<xs:simpleType name="shortString">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
<!-- Restrict to specific values (enumeration) -->
<xs:simpleType name="sizeType">
<xs:restriction base="xs:string">
<xs:enumeration value="small"/>
<xs:enumeration value="medium"/>
<xs:enumeration value="large"/>
</xs:restriction>
</xs:simpleType>
<!-- Restrict using pattern (regex) -->
<xs:simpleType name="phoneNumber">
<xs:restriction base="xs:string">
<xs:pattern value="\d{3}-\d{3}-\d{4}"/>
</xs:restriction>
</xs:simpleType>
<!-- Restrict numeric range -->
<xs:simpleType name="percentage">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>Occurrence Constraints
Control how many times an element can appear using minOccurs and maxOccurs:
<xs:element name="item" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
<!-- Element must appear at least once, with no upper limit -->
<xs:element name="middleName" type="xs:string" minOccurs="0"/>
<!-- Optional element (0 or 1 occurrences) -->
<xs:element name="phone" type="xs:string" minOccurs="1" maxOccurs="3"/>
<!-- Must have 1-3 phone numbers -->Complete Example
Here's a complete XSD schema for a bookstore:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Simple type for ISBN format -->
<xs:simpleType name="isbnType">
<xs:restriction base="xs:string">
<xs:pattern value="\d{3}-\d{10}"/>
</xs:restriction>
</xs:simpleType>
<!-- Simple type for book categories -->
<xs:simpleType name="categoryType">
<xs:restriction base="xs:string">
<xs:enumeration value="fiction"/>
<xs:enumeration value="non-fiction"/>
<xs:enumeration value="technical"/>
<xs:enumeration value="children"/>
</xs:restriction>
</xs:simpleType>
<!-- Complex type for author -->
<xs:complexType name="authorType">
<xs:sequence>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="lastName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<!-- Complex type for book -->
<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="authorType" maxOccurs="unbounded"/>
<xs:element name="price" type="xs:decimal"/>
<xs:element name="publishDate" type="xs:date"/>
</xs:sequence>
<xs:attribute name="isbn" type="isbnType" use="required"/>
<xs:attribute name="category" type="categoryType"/>
</xs:complexType>
<!-- Root element -->
<xs:element name="bookstore">
<xs:complexType>
<xs:sequence>
<xs:element name="book" type="bookType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>Best Practices
- Use named types: Define reusable types for elements that share the same structure.
- Add documentation: Use xs:annotation and xs:documentation to describe your schema elements.
- Be specific with types: Use the most restrictive data type that fits your needs.
- Use enumerations: When values are limited to a known set, enumerate them.
- Version your schemas: Include version information in your schema namespace.
Generate XSD from Your XML
Don't want to write XSD by hand? Use our free tool to automatically generate a schema from your XML: