XML Schema Validation Guide

May 28, 20265 min read

What Is XML Schema Validation?

Well-formed XML follows syntax rules — tags close properly, attributes are quoted, and one root element wraps everything. Valid XML goes further: it conforms to a schema that defines what elements and attributes are allowed, in what order, with what data types.

The most common schema language is XSD (XML Schema Definition). An XSD file describes the blueprint your XML must follow.

Why Validate Against a Schema?

Without SchemaWith Schema
Any element name worksOnly declared elements allowed
Text appears anywhereContent restricted to defined types
Attributes are unconstrainedAttributes must match declared types
Optional/required is ambiguousminOccurs/maxOccurs enforce cardinality
Errors surface at parsing timeErrors caught at validation time — earlier and clearer

Schema validation catches data problems before they reach your application logic.

Basic XSD Structure

An XSD defines types using <element>, <attribute>, and <simpleType>/<complexType>:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="bookstore">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book" maxOccurs="unbounded">
          <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="id" type="xs:integer" use="required"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

This schema requires:

  • A root <bookstore> element
  • One or more <book> children (maxOccurs="unbounded")
  • Each <book> has <title>, <author>, <price> in that order
  • Each <book> has a required integer id attribute
  • <price> must be a decimal number

XSD Data Types

XSD provides built-in types for precise validation:

TypeDescriptionExample
xs:stringText"Hello"
xs:integerWhole number42
xs:decimalFixed-point number29.99
xs:booleanTrue/falsetrue
xs:dateDate (YYYY-MM-DD)2026-05-28
xs:dateTimeDate and time2026-05-28T14:30:00
xs:emailEmail format (via pattern)user@example.com
xs:anyURIURI referencehttps://example.com
xs:tokenWhitespace-normalized string"hello world"

Restricting Values with simpleType

Custom types add constraints beyond built-in types:

<!-- Enum: only specific values allowed -->
<xs:simpleType name="genreType">
  <xs:restriction base="xs:string">
    <xs:enumeration value="fiction"/>
    <xs:enumeration value="nonfiction"/>
    <xs:enumeration value="biography"/>
  </xs:restriction>
</xs:simpleType>

<!-- Pattern: regex constraint -->
<xs:simpleType name="isbnType">
  <xs:restriction base="xs:string">
    <xs:pattern value="\d{3}-\d{1,5}-\d{1,7}-\d{1}"/>
  </xs:restriction>
</xs:simpleType>

<!-- Range: numeric bounds -->
<xs:simpleType name="priceType">
  <xs:restriction base="xs:decimal">
    <xs:minInclusive value="0.01"/>
    <xs:maxExclusive value="999.99"/>
  </xs:restriction>
</xs:simpleType>

Cardinality Control

AttributeMeaningDefault
minOccursMinimum occurrences1
maxOccursMaximum occurrences1
maxOccurs="unbounded"No upper limit
<!-- Required element, exactly one -->
<xs:element name="title" type="xs:string"/>

<!-- Optional element, zero or one -->
<xs:element name="subtitle" type="xs:string" minOccurs="0"/>

<!-- One to five authors -->
<xs:element name="author" type="xs:string" maxOccurs="5"/>

<!-- Unlimited reviews -->
<xs:element name="review" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>

Sequence vs Choice vs All

CompositorBehavior
<xs:sequence>Elements must appear in order
<xs:choice>Exactly one of the listed elements
<xs:all>Elements appear in any order, each at most once
<!-- Either a book or a magazine, not both -->
<xs:choice>
  <xs:element name="book" type="bookType"/>
  <xs:element name="magazine" type="magazineType"/>
</xs:choice>

Validating XML Against XSD

Command Line

# Using xmllint
xmllint --schema books.xsd books.xml --noout

# Using Java
java -jar jing.jar books.xsd books.xml

JavaScript (Browser)

const parser = new DOMParser();
const doc = parser.parseFromString(xmlString, 'application/xml');
// Browser validators check well-formedness only —
// Full XSD validation requires a server-side tool

Python

from lxml import etree

schema_root = etree.parse('books.xsd')
schema = etree.XMLSchema(schema_root)

doc = etree.parse('books.xml')
is_valid = schema.validate(doc)
# True or False

if not is_valid:
    for error in schema.error_log:
        print(f"Line {error.line}: {error.message}")

Common Validation Errors

ErrorCauseFix
"Element not expected"Undeclared elementAdd element to schema
"Attribute not allowed"Undeclared attributeAdd attribute to complexType
"Text not allowed"Text in element-only contentWrap text in a child element
"Value not valid"Wrong data typeMatch the declared type
"Missing required attribute"use="required" not satisfiedAdd the attribute to XML

Key Takeaways

  • Schema validation catches structural and type errors that well-formedness checks miss
  • XSD defines allowed elements, attributes, order, cardinality, and data types
  • simpleType with restrictions enforces enums, patterns, and numeric ranges
  • minOccurs and maxOccurs control element frequency
  • Use command-line tools or language libraries to validate XML against XSD before processing
  • Always validate XML from external sources — never trust structure

Try It Yourself

Format and validate your XML documents with our XML Formatter. Paste messy XML, format it for readability, and check well-formedness instantly.