Back to Guides
Schema Design18 min read

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 strings
  • xs:integer - Whole numbers
  • xs:decimal - Decimal numbers
  • xs:boolean - true/false values
  • xs: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: