What is XSD, and what does it stand for?
XSD stands for XML Schema Definition. It is the W3C language for saying which XML documents belong to a vocabulary. The XSD Primer, a W3C Recommendation whose second edition is dated 28 October 2004, states the purpose in one line: the purpose of a schema is to define a class of XML documents.
An XSD can require a root element, order child elements in a sequence, allow alternatives, control repetition, define attributes and constrain text to datatypes or value ranges. It also gives every declaration an identity in a namespace. Messages in formats built on XML, such as SOAP, are described this way too; SOAP vs REST shows one of them next to its REST counterpart.
A schema is itself XML. The first part of the specification describes the schema language as being itself represented in XML 1.0, so any tool that reads XML can read a schema. The file extension .xsd is a convention: the specifications name the media types application/xml and text/xml for schema documents and mention the extension only in examples.
The Primer addresses authors who need functions above and beyond what DTDs provide. The most visible gain is datatypes: a quantity can be required to be a whole number, a date to be a date.
Schema validation adds information beyond XML parsing. The XML Formatter can confirm well-formed syntax, but only an XSD processor can determine whether a parsed document satisfies a schema set.
Anatomy of a schema document
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://example.com/catalog"
xmlns:tns="https://example.com/catalog"
elementFormDefault="qualified">
<xs:element name="catalog" type="tns:CatalogType"/>
</xs:schema> The xs prefix refers to the XML Schema vocabulary. targetNamespace identifies the declarations created by the schema. The tns prefix is a convenient binding used when those declarations are referenced by QName. Some documents write the prefix as xsd instead of xs; any prefix bound to the same namespace works.
What is the difference between XSD and XML?
XML is the syntax. An XSD is a description, written in that syntax, of the documents a vocabulary permits. A document is an instance, and the schema says what an instance may look like.
Two checks follow from this. The first is well-formedness, defined by XML 1.0: the tags nest properly, attributes are quoted, there is one root. A document that breaks a well-formedness rule produces a fatal error. The second is validity against a schema. XML 1.0 itself uses the word valid for documents that conform to a document type declaration. With XSD the check is called schema-validity assessment, which is why the phrase valid against the XSD is the exact one.
| Check | Question | Done by | Fails for |
|---|---|---|---|
| Well-formed | Is the syntax correct XML? | Any XML parser | <a><b></a></b>, tags in the wrong order |
| Valid against the XSD | Does the document satisfy the declarations? | A schema processor | <quantity>five</quantity> where a number is required |
The second row shows a document that parses without complaint and still fails: the XML is syntactically fine, and the schema says quantity is a whole number. For how XML compares with another common data format, see XML vs JSON.
XML Schema example: a purchase order, step by step
The pair at the top of the page is a small order. The structure follows the purchase order used in the Primer: a sequence of child elements, an optional comment element, a whole number with an upper limit. Reading the XSD from the top gives six steps.
- The element named
order is declared at the top level, so it is the only element that may start a document. Its type is a complex type, because it has child elements and an attribute. - Inside it,
xs:sequence fixes the order of the children: customer, then quantity, then note. - The customer is a plain
xs:string, one of the datatypes built into the language. - The quantity gets a type of its own: a restriction of
xs:positiveInteger with the facet maxExclusive set to 100. Valid values are therefore the whole numbers from 1 to 99. - The note carries
minOccurs="0", which makes it optional. The default for an element is exactly one occurrence. - The date is an attribute of type
xs:date and is required, so an order without one is invalid.
Validation passes for the sample. Changing it breaks the document in specific ways, and a processor names each one. These messages came from xmllint with libxml 2.9.13; other processors and versions word them differently.
quantity is "five":
Element 'quantity': 'five' is not a valid value of the local atomic type.
quantity is "100":
Element 'quantity': [facet 'maxExclusive'] The value '100' must be less than '100'.
customer element removed:
Element 'quantity': This element is not expected. Expected is ( customer ).
date is "14.03.2026":
Element 'order', attribute 'date': '14.03.2026' is not a valid value of the atomic type 'xs:date'.
The sequence matters as much as the types. The schema lists customer before quantity, so a document with the two swapped is rejected even though each element on its own is fine. That strictness is useful for documents exchanged between systems, because both sides can rely on one order.
A value of 99 passes, and 0 fails because it is not a positive integer. Testing a boundary from both sides is the quickest way to confirm that a facet says what you meant.
How are elements, attributes and types declared?
An element declaration gives an XML element its name and type. A simple type describes atomic text values, lists or unions, and it constrains text or attribute values without child elements. A complex type describes child content and attributes, and it is the one that allows mixed content too. Types can be built in, named globally for reuse, or anonymous inside a declaration, as the quantity in the example is.
<xs:complexType name="ProductType">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="sku" type="xs:string" use="required"/>
</xs:complexType>
Declaration Describes In the example xs:elementAn element name and its type customer, quantity, note xs:attributeAn attribute on an element date xs:simpleTypeText values, restricted, listed or combined The limited quantity xs:complexTypeChild elements, attributes, mixed content The order itself
A named type can be used by several elements, while an anonymous type belongs to the one declaration that contains it and cannot be referred to from elsewhere. Deciding whether identity or structure is the reusable concept is the subject of the guide to element references versus named types.
How do cardinality and value constraints work?
minOccurs and maxOccurs control how many times an element particle can occur. Simple-type facets constrain values with ranges, lengths, patterns and enumerations. In XSD 1.0 there are twelve facets in all, defined in Part 2 of the specification, and XSD 1.1 adds two. The enumeration facet limits a value to a fixed set, which suits a status code or a country list.
Constraint Purpose Example minOccurs="0"Element may be absent Optional note maxOccurs="unbounded"Repeat without schema limit Line items xs:enumerationClosed value set Status code xs:patternLexical pattern Identifier syntax
Patterns and enumerations answer different needs. An enumeration lists every allowed value, which fits a closed set that changes rarely. A pattern describes the shape of a value, such as a product code made of two letters and four digits, and accepts anything of that shape whether or not the product exists. Neither can look anything up elsewhere, so a schema can say that a code is well-formed and cannot say that it is in use.
Restrictions should reflect domain rules, and they should be tested with boundary examples. A limit of 99 that is wrong by one only surfaces when someone orders 100. The schema is a contract: values it forbids cannot enter the system through a validating interface, and values it allows must be ones the rest of the system can handle.
How do I create an XSD for an XML document?
- Collect sample documents. Use real ones, not a single tidy example. Optional parts and repetitions only show up across several.
- Fix the root element. Decide which element may start a document and declare it at the top level.
- Derive the types. Elements with children get complex types, text-only elements get simple types, and structures that repeat get a named type.
- Mark repetitions and optional parts. Set
minOccurs and maxOccurs where the samples differ, and think about what the data can really do rather than what the samples happened to contain. - Add value limits. Use built-in datatypes first, then facets such as enumeration, pattern and ranges.
- Validate and attack the result. Every sample must pass. Then write documents that should fail, such as a missing required element or a value just outside a limit, and confirm each one is rejected.
The order of work is deliberate. Types come before limits, because a limit only makes sense once the type is known, and limits come before validation, because a schema with no constraints accepts nearly anything and every test passes by default. The adversarial documents in the last step are what turn the schema from a description into a check.
Generators exist that infer a schema from sample documents. Their output is a draft: it reflects only what the samples contained, so the limits and the optional parts need the review above.
How do I validate XML against an XSD?
A validator takes two inputs, the instance document and the schema set, and reports either success or each violation. On the command line, xmllint does it in one call:
xmllint --noout --schema order.xsd order.xml
order.xml validates
For a document that does not conform, the same command lists the errors, as in the examples above. Running the formatter first is a quick way to find syntax problems: a document that is not well-formed never reaches the schema check, so those errors come first and the schema errors only after they are fixed.
When a document fails, the messages are read from the top. The first error often causes the later ones, as when a missing required element makes the validator complain about the next element in line. Fixing the first message and running the check again is faster than working through the whole list.
A document may point to its schema with xsi:schemaLocation or xsi:noNamespaceSchemaLocation. The specification describes these as hints about the physical location of schema documents. An application is free to ignore a hint and to take the schema from a source of its own. As an editorial reading, a hint inside a document is not a statement of trust: the schema should come from a controlled location, and a validator should not fetch it from whatever address an incoming document names.
How do include and import combine schema documents?
A vocabulary can span several schema documents, and one XML document can be validated against the whole set. xs:include combines documents for the same target namespace. A document that has no target namespace can be included too, and its declarations take on the namespace of the including schema. xs:import makes declarations from another namespace available. Relative locations, catalogs and resolver policies must work consistently in development, CI and production.
A production validator should load the complete schema set under an explicit resource policy. Avoid depending on uncontrolled remote network retrieval during validation. The behaviour is easy to test: in a trial with xmllint, an include whose target namespace differed from the including schema stopped with an error that named the difference.
What is XSD 1.1, and does XSD check business rules?
XSD 1.1 is a W3C Recommendation of 5 April 2012. Part 1 adds two features to the language: conditional type alternatives, where the type of an element is chosen by a test, and assertions, which attach conditions written with XPath to a type. Both are described in Part 1, in sections 3.12 and 3.13.
Processor support must be checked before a schema relies on them. In a trial, xmllint from libxml 2.9.13 could process only XSD 1.0 and refused to compile a schema that used xs:assert. A 1.1 schema therefore needs a processor that implements 1.1, and an example written for one should be run against such a processor before it is trusted.
As for business rules, XSD covers structure and datatypes well. A rule that compares two fields, such as an end date that must not precede a start date, is contextual. With version 1.1 it can be written as an assertion. Otherwise it needs a separate rule language or a validation layer in the application. XML representations of resources in an API can be described with XSD as well, and REST web services covers where schemas sit among the other contract formats.
Continue the learning path
- Compare global and local XSD design patterns.
- Apply the XML Schema best-practice checklist.
- Learn rule-based validation with Schematron.
- Plan compatible changes with the schema versioning guide.
- Inspect a real XSD with the Pattern Analyzer.
Frequently asked questions
01What does XSD stand for?
XSD stands for XML Schema Definition. It is the W3C language for describing which XML documents belong to a vocabulary, and a schema written in it is itself an XML document.
02What is the difference between XSD and XML?
XML is the syntax a document is written in. An XSD is a description, written in XML, of the documents a vocabulary allows: which elements and attributes may appear, in what order, with which datatypes. A processor compares the one against the other.
03How to create an XSD?
Start from a few real sample documents, declare the root element, derive types for the repeating parts, set the occurrence limits and value constraints, and then validate the samples. Add documents that should fail and check that they do. A generator can produce a first draft, but the draft still needs this review.
04How to use XSD to validate XML?
Give a schema processor the XML document and the schema, and it reports whether the document conforms or lists the violations. Command-line tools and libraries do this for XSD. The schema should come from a source you control, not from a location named inside the document.
05Is a well-formed XML document automatically valid?
No. Well-formed means the syntax follows the XML rules. A document is valid against an XSD only if it also satisfies the declarations and constraints of that schema, so a well-formed document can still fail.
06What is an XSD file?
It is a text file that contains a schema document, an XML document whose root element is xs:schema. The extension .xsd is a convention. The W3C specifications speak of media types such as application/xml, and a schema document can be opened in any text editor.