XSD guide
XSD complex type extension vs restriction
Choose type derivation based on whether the accepted instance set grows or narrows, and avoid restrictions that are not valid subsets of their base type.
8 min read · Updated 2026-08-21
The short answer
Use extension when the derived complex type keeps the base content and adds elements or attributes. Use restriction when every instance accepted by the derived type is also accepted by the base type and the derived declaration deliberately narrows the allowed set. Restriction is a subset contract, not a way to edit or replace arbitrary parts of the base model.Choose by the direction of the value set
Extension grows what the type describes while preserving the base content. Restriction narrows occurrences, choices, wildcards, or allowed attributes subject to the schema's derivation rules. Ask whether a consumer prepared for the base type can safely accept every derived value.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="BaseRecord">
<xs:sequence><xs:element name="id" type="xs:string"/></xs:sequence>
</xs:complexType>
<xs:complexType name="DetailedRecord">
<xs:complexContent><xs:extension base="BaseRecord">
<xs:sequence><xs:element name="note" type="xs:string" minOccurs="0"/></xs:sequence>
</xs:extension></xs:complexContent>
</xs:complexType>
</xs:schema>Treat restriction as a provable subset
A restriction can make an optional child required, reduce a maximum occurrence, select fewer alternatives, or prohibit an optional attribute when the resulting model remains validly substitutable for the base. It cannot casually reorder required particles or introduce content the base never allowed.
- Write representative values accepted by both base and derived types.
- Write a base-valid value that the restriction intentionally rejects.
- Let the schema compiler verify the derivation itself.
- Use composition instead when the models are related only conceptually.
Validate the schema before validating instances
An invalid restriction is an error in the schema, so no instance tweak can repair it. Compile the complete schema set first, including imports and includes, then validate boundary instances against both the base and derived types.
Document whether xsi:type or substitution is expected at runtime and whether the base type blocks a derivation method. final controls creation of derived types; block controls their use in place of a declared type.
Prove the fix
- Compile the complete schemaCatch an invalid derivation before interpreting any instance errors.
- Review complex typesConnect content models, attributes, and derivation containers.
- Compare schema languagesConsider composition alternatives when inheritance obscures the contract.
Related guides
- How to validate XML against an XSDSeparate parsing from schema validation, load the complete schema set, and reduce validation errors to the smallest failing instance.
- XSD sequence vs choiceWhen child order is fixed, when alternatives are exclusive, and how minOccurs and maxOccurs change the meaning of an XSD compositor.
- XSD include vs importUse xs:include for one namespace and xs:import across namespaces, then make schema resolution deterministic in local and deployed environments.
Get started
Bring order to the XML your team can't afford to ignore.
Create a free account and get a private workspace to search, validate, diff, and monitor your XML feeds, sitemaps, schemas, and vendor integrations.