Skip to content
Quasar Tools Logo

How to Validate XML Against an XSD Schema

Complete guide to XML XSD validation: what XSD checks, how to validate XML against a schema online and in code, common errors, and how to fix them fast.

DH
Tutorials & How-Tos12 min read2,700 words

An XML document that parses without errors is well-formed — but well-formed is not the same as correct. XSD validation goes one level deeper, checking every element against a contract: required fields are present, data types match, values fall within allowed ranges, and elements appear in the right order. This guide explains exactly what XSD validation checks, how to run it online and in code, what the most common errors mean, and how to build XSD validation into your CI pipeline so broken documents never reach production.

2Validation levelswell-formedness + schema validity
100%Browser-local checksno XML leaves your device
<1sValidation speedinstant feedback on errors

What is XSD validation?

XSD stands for XML Schema Definition. It is a W3C standard that lets you describe the exact structure an XML document must follow: which elements are allowed, what order they appear in, what data types their content must match, and which attributes are required or optional. When you validate an XML document against an XSD, a parser reads both files and reports every place the document deviates from the schema contract.

XSD replaced the older DTD (Document Type Definition) format as the primary XML schema language because it is itself written in XML, supports a rich set of built-in data types (`xs:integer`, `xs:date`, `xs:boolean`, etc.), and can express complex constraints like string patterns, numeric ranges, and conditional element requirements. DTDs are still encountered in legacy systems, but XSD is the standard for any XML-based data exchange built in the last fifteen years.

Where XSD validation is used

XSD validation appears wherever structured XML data crosses a system boundary. Common examples include SOAP web service requests and responses (described by WSDL, which embeds XSD schemas), e-invoicing and procurement formats like UBL 2.1 and EDIFACT, healthcare data exchange using HL7 CDA and FHIR XML profiles, government XML filings (tax returns, customs declarations), and configuration files for enterprise software like Maven's `pom.xml` or Spring's application context XML.

  • SOAP / WSDL services: Every request and response element is defined in an embedded XSD.
  • E-invoicing (UBL, CII): Procurement and invoice formats carry public XSD schemas that trading partners validate against.
  • Healthcare (HL7, FHIR XML): Clinical document exchange requires strict XSD conformance before acceptance.
  • Government filings: Tax authorities and customs agencies publish XSD schemas that submitted documents must satisfy.
  • Build tooling: Maven pom.xml, Ant build.xml, and many other config formats use XSD for IDE auto-complete and validation.

Note

XSD validation is distinct from XML namespace correctness. A document can reference the right namespace URI and still fail XSD validation if its content violates the schema constraints. Always validate against the schema, not just the namespace declaration.

Well-formedness vs. validity

Every XML document must first be well-formed before it can be validated. Well-formedness is checked by the XML parser itself, with no schema needed. Validity is an additional layer checked against a specific schema. Understanding the distinction saves significant debugging time — an XSD validator that receives a malformed document will often report confusing schema errors instead of the real parse-level problem.

A textual object is a well-formed XML document if it matches the production labeled document and satisfies all the well-formedness constraints given in the specification.

W3C XML Specification

What well-formedness checks

  • Tag matching: Every opening tag has a corresponding closing tag (`&lt;item&gt;` → `&lt;/item&gt;`).
  • Proper nesting: Tags must close in reverse order — `&lt;a&gt;&lt;b&gt;&lt;/b&gt;&lt;/a&gt;` is valid; `&lt;a&gt;&lt;b&gt;&lt;/a&gt;&lt;/b&gt;` is not.
  • Single root element: The document has exactly one top-level element.
  • Quoted attributes: All attribute values are wrapped in single or double quotes.
  • Escaped special characters: `&lt;`, `&gt;`, `&`, `"` and `'` inside text content must use entity references or CDATA sections.
  • Valid element and attribute names: Names start with a letter or underscore, not a digit or hyphen.

What XSD validity adds on top

Once well-formedness passes, XSD validation layers on the schema contract. This includes checking that every element declared as required by `minOccurs="1"` is actually present, that text content in typed elements matches the declared `xs:type` (no strings in integer fields), that numeric values fall within `xs:minInclusive` and `xs:maxInclusive` bounds, that string content satisfies `xs:pattern` regex restrictions, and that child elements appear in the sequence, choice, or all group defined in the schema.

CheckWell-formednessXSD validity
Tag matching and nesting✓ Yes✓ Prerequisite
Single root element✓ Yes✓ Prerequisite
Required elements present✗ No✓ Yes — minOccurs
Data type correctness✗ No✓ Yes — xs:integer, xs:date, etc.
Numeric range constraints✗ No✓ Yes — minInclusive/maxInclusive
String pattern matching✗ No✓ Yes — xs:pattern
Element ordering✗ No✓ Yes — xs:sequence / xs:choice
Allowed attribute values✗ No✓ Yes — xs:enumeration

XML Well-Formedness Checker

Check your XML document for malformed tags, invalid nesting, missing root elements, and entity errors — browser-local with line-level diagnostics.

Open tool

Anatomy of an XSD schema

Before you can validate XML against an XSD, you need to understand what an XSD file contains. A schema file is itself a valid XML document, with a root element of `xs:schema` in the `http://www.w3.org/2001/XMLSchema` namespace. Everything inside the schema describes what the target XML documents must look like.

invoice.xsd
xml
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- Root element declaration --&gt;
  <xs:element name="Invoice">
    <xs:complexType>
      <xs:sequence>
        <!-- Required string — must be present exactly once --&gt;
        <xs:element name="InvoiceNumber" type="xs:string" minOccurs="1" maxOccurs="1"/>
        <!-- Required date --&gt;
        <xs:element name="IssueDate"     type="xs:date"   minOccurs="1" maxOccurs="1"/>
        <!-- Required positive integer --&gt;
        <xs:element name="TotalAmount"   type="xs:decimal" minOccurs="1" maxOccurs="1"/>
        <!-- Optional — 0 to many line items --&gt;
        <xs:element name="LineItem"      type="LineItemType" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <!-- Required attribute --&gt;
      <xs:attribute name="currency" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>

  <!-- Reusable complex type definition --&gt;
  <xs:complexType name="LineItemType">
    <xs:sequence>
      <xs:element name="Description" type="xs:string"/>
      <xs:element name="Quantity"    type="xs:positiveInteger"/>
      <xs:element name="UnitPrice"   type="xs:decimal"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

Key XSD concepts

  • xs:element: Declares an element by name and type. `minOccurs` and `maxOccurs` control cardinality.
  • xs:complexType: Defines an element that contains child elements or attributes (not just text).
  • xs:simpleType: Defines a type derived from a built-in type — used to add restrictions like patterns or enumerations.
  • xs:sequence: Child elements must appear in the exact order listed.
  • xs:choice: Exactly one of the listed child elements must appear.
  • xs:all: All listed child elements must appear, in any order, each exactly once.
  • xs:attribute: Declares an attribute on a complex element. `use="required"` makes it mandatory.
  • xs:restriction: Adds constraints to a base type — `xs:pattern`, `xs:minInclusive`, `xs:enumeration`, etc.

Tip

You can generate a draft XSD from an existing XML document using tools that infer the schema from sample data. Always review and tighten the generated output — inferred schemas tend to make every element optional and leave types as `xs:string` until you manually add proper type declarations and cardinality constraints.

How to validate XML against XSD

There are three practical ways to validate an XML document against an XSD schema: a browser-based tool for quick checks, a command-line tool for local development and scripting, and a programmatic approach for integration into application code or CI pipelines. All three approaches report the same categories of errors — the difference is where and how you run the validation.

1

Check well-formedness first

Before running XSD validation, confirm the XML document is well-formed. Use the XML Well-Formedness Checker to catch structural errors — a malformed document will produce misleading XSD errors and waste debugging time. Fix all parser-level issues first, then proceed to schema validation.

2

Validate online with Quasar Tools XML Validator

Open the XML Validator, paste your XML document into the left panel and your XSD schema into the right panel, then run the validation. The tool processes both files entirely in your browser — no data is uploaded. Each validation error is reported with the element path, the violated constraint, and the line number in the source document.

3

Validate on the command line with xmllint

For local development and scripting, `xmllint` from the libxml2 package is the standard CLI choice. Run `xmllint --schema schema.xsd document.xml --noout` — the `--noout` flag suppresses the document echo so only errors are printed. A clean exit with no output means the document is valid. On macOS, install via `brew install libxml2`; on Ubuntu/Debian, `apt-get install libxml2-utils`.

4

Validate programmatically in Java, Python, or .NET

For application-level validation, use your language's built-in XML library. Java's `javax.xml.validation` package (Xerces), Python's `lxml.etree.XMLSchema`, and .NET's `XmlSchemaSet` with `XmlReader` all support XSD validation with a few lines of code. Integrate the validation call at your API boundary or file ingestion point to reject invalid documents before they reach business logic.

terminal
bash
# Validate document.xml against schema.xsd using xmllint
xmllint --schema schema.xsd document.xml --noout

# Output on success:
document.xml validates

# Output on failure:
document.xml:12: element TotalAmount: Schemas validity error:
Element 'TotalAmount': 'abc' is not a valid value of the
atomic type 'xs:decimal'.

XML Validator

Validate XML documents for well-formedness and schema compliance — browser-local with no upload required, line-level error reporting.

Open tool

Common XSD validation errors

XSD validation errors fall into predictable categories. Understanding what each error type means lets you locate and fix the problem in the source document quickly, rather than decoding unfamiliar validator output line by line.

Type mismatch errors

Type errors occur when element or attribute content does not match the declared `xs:type`. The most common: a text string like `"N/A"` in a field declared as `xs:integer`, a date in the wrong format (e.g. `15/06/2026` instead of `2026-06-15`) in an `xs:date` field, or a decimal in a field declared as `xs:positiveInteger`. Fix by correcting the value in the source document or adjusting the type declaration in the schema if the current type is too restrictive.

Missing required elements

When `minOccurs="1"` (the default for `xs:element`) and the element is absent from the instance document, the validator reports: `Element 'X': This element is not expected. Expected is one of ( Y )` or `Element 'X' is missing`. This typically means the producer of the XML omitted a mandatory field. Check the schema's `xs:sequence` to confirm which elements are required in which position.

Unexpected or undeclared elements

If your schema does not use `xs:any` and does not set `processContents="lax"`, any element not declared in the schema will produce: `Element 'X': This element is not expected`. This is the most common error when an XML producer adds a new field without updating the schema, or when the document contains a namespace prefix that is not declared. Check the element name, the parent element context, and the namespace declarations at the top of the document.

Pattern and enumeration violations

XSD supports `xs:pattern` (a regex) and `xs:enumeration` (an allowed value list) as facets on simple types. A violation looks like: `Element 'Status': [facet 'enumeration'] The value 'ACTIVE' is not an element of the set active', 'inactive', 'pending`. Check whether the schema uses case-sensitive enumeration values and whether the instance document matches the expected casing exactly.

Error typeTypical message fragmentHow to fix
Type mismatch'abc' is not a valid xs:integerCorrect the value or loosen the type
Missing element'InvoiceNumber' is missingAdd the required element to the document
Unexpected element'Notes': This element is not expectedRemove the element or add it to the XSD
Enumeration failureValue 'ACTIVE' not in setMatch casing of schema enum values
Pattern violationValue fails xs:pattern restrictionFix value to match the regex pattern
Sequence orderExpected is 'IssueDate' not 'Total'Reorder elements to match xs:sequence
CardinalityElement 'Item' can occur max 1 timesRemove duplicate or raise maxOccurs

Warning

Element order errors are particularly easy to miss. An `xs:sequence` declaration requires elements to appear in the listed order — even if all elements are present and have valid values, being out of order causes a schema validation failure. Always check the sequence definition in the XSD when you see "This element is not expected" errors on elements you know exist.

XSD validation in code and CI/CD

Manual validation works for one-off checks, but production XML workflows need automated validation at every integration point. Adding XSD validation to your application code and CI pipeline ensures invalid documents are rejected before they cause data corruption, processing failures, or compliance violations downstream.

Validating in Python with lxml

validate_xml.py
python
from lxml import etree

def validate_against_xsd(xml_path: str, xsd_path: str) -&gt; list[str]:
    """Returns a list of validation error messages, empty if valid."""
    with open(xsd_path, 'rb') as f:
        schema_doc = etree.parse(f)
    schema = etree.XMLSchema(schema_doc)

    with open(xml_path, 'rb') as f:
        doc = etree.parse(f)

    schema.validate(doc)
    return [str(e) for e in schema.error_log]

errors = validate_against_xsd('invoice.xml', 'invoice.xsd')
if errors:
    for err in errors:
        print(err)
else:
    print('Document is valid.')

Adding XSD validation to GitHub Actions

For CI/CD workflows that process or generate XML, a validation step prevents broken documents from merging. The `xmllint` command is available on GitHub Actions Ubuntu runners via `sudo apt-get install -y libxml2-utils`. Add a step that runs `xmllint --schema schema.xsd document.xml --noout` on every pull request that touches XML files. A non-zero exit code fails the check and blocks the merge.

.github/workflows/xml-validate.yml
yaml
name: Validate XML
on:
  pull_request:
    paths:
      - '**/*.xml'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install xmllint
        run: sudo apt-get install -y libxml2-utils
      - name: Validate XML against XSD
        run: |
          xmllint --schema schemas/invoice.xsd                   data/invoices/*.xml                   --noout

Using XPath to inspect specific values before validation

Before running a full XSD pass, you can use the XPath Finder and Tester to pinpoint the value of a specific element or attribute in a large XML document. XPath queries like `//Invoice/TotalAmount/text()` retrieve a field without parsing the entire file manually. This is especially useful when diagnosing a type mismatch in a document with hundreds of elements — locate the offending value first, then apply the fix.


Validation approach comparison

ApproachSpeedPrivacySchema supportBest for
Quasar Tools XML ValidatorInstant✓ Browser-localWell-formed + XSDQuick one-off checks
xmllint CLIFast✓ Local machineXSD, DTD, RelaxNGDev scripts and CI/CD
lxml / Xerces / .NETFast✓ In-processXSD (full spec)Application code
Online server toolsModerate✗ Data uploadedVariableAvoid for sensitive schemas

XSD best practices

A well-designed XSD schema makes documents easier to validate, easier to extend, and easier to maintain across schema versions. These practices apply whether you are authoring a schema from scratch or maintaining one received from an external partner.

Use named types instead of anonymous inline types

Define complex types with `xs:complexType name="..."` rather than nesting them anonymously inside element declarations. Named types can be reused across multiple element declarations, reducing repetition and making schema changes easier — update the type definition once and all elements using it inherit the change.

Prefer xs:sequence over xs:all for strict contracts

`xs:all` allows elements to appear in any order, which seems permissive but introduces ambiguity for producers and consumers. `xs:sequence` is more explicit and matches the natural reading order of most XML formats. Use `xs:all` only when element order genuinely does not matter and you are authoring the schema for a system you control; prefer `xs:sequence` for any schema that crosses organizational boundaries.

Version your schemas with a namespace

Use a target namespace URI that includes a version indicator, such as `targetNamespace="urn:example:invoice:v2"`. This makes breaking schema changes explicit — consumers on v1 will see a namespace mismatch rather than silently validating against the wrong schema version. Keep the old schema available for backward-compatible deployments during the migration window.

  • Declare a targetNamespace: Avoids element name collisions when schemas are composed together via xs:import.
  • Use xs:documentation: Add human-readable descriptions inside xs:annotation blocks so schema consumers understand each field.
  • Set explicit minOccurs/maxOccurs: Never rely on the default — state cardinality explicitly to communicate intent.
  • Use xs:restriction for constrained strings: A postcode field should use xs:pattern, not xs:string — validation catches format errors at the boundary.
  • Split large schemas: Use xs:include to split a 500-line schema into per-domain files (addresses.xsd, line-items.xsd) for easier maintenance.

Tip

After editing an XSD, always re-validate your existing test documents against the updated schema. A schema change that tightens a constraint can silently invalidate documents that were previously valid. Use the [XML Validator](/tools/data/validators/xml-validator) to run a quick regression check on your canonical test fixtures before publishing the updated schema.

Note

If you work with XML data that needs to be consumed by REST APIs or JavaScript applications, the [XML to JSON Converter](/tools/data/converters/xml-json-converter) converts validated XML documents to JSON format while preserving the element hierarchy and attribute values.

Key takeaways

  • XSD validation checks an XML document against a schema contract — element types, required fields, value ranges, and ordering — beyond basic well-formedness.
  • Always confirm well-formedness with the XML Well-Formedness Checker before running XSD validation to avoid misleading error output.
  • The most common XSD errors are type mismatches, missing required elements, unexpected elements, and xs:sequence ordering violations.
  • Use `xmllint --schema schema.xsd document.xml --noout` on the command line for fast local validation and CI/CD integration.
  • Add an XSD validation step to your GitHub Actions workflow to block invalid XML documents from merging into the main branch.
  • Design XSD schemas with named types, explicit cardinality, target namespaces, and xs:restriction facets to create schemas that are both strict and maintainable.
  • Use the XPath Finder and Tester to locate specific values in large XML documents before and after validation.

Frequently Asked Questions

XSD validation is the process of checking an XML document against an XML Schema Definition (XSD) file to confirm it meets all defined structural and data constraints. It goes beyond well-formedness checks — which only verify that the XML is syntactically correct — by enforcing element order, data types, value ranges, string patterns, and which elements are required or optional. A document that is well-formed but fails XSD validation is called invalid.

A well-formed XML document follows the basic XML syntax rules: every opening tag has a matching closing tag, tags are properly nested, attribute values are quoted, and there is exactly one root element. A valid XML document is well-formed AND conforms to a specific schema (DTD, XSD, or Relax NG) that defines the allowed elements, attributes, types, and constraints. Well-formedness is checked by any XML parser; validity requires the schema file to be present during the check.

The quickest approach is to use the Quasar Tools XML Validator, which runs entirely in your browser. Paste your XML document into the first panel and your XSD schema into the second, then click Validate. The tool reports each constraint violation with the element path and line number. No file is uploaded to a server — all processing happens locally, which makes it safe for schemas that contain proprietary data structures or sensitive field names.

Run the command: xmllint --schema yourschema.xsd yourdocument.xml --noout. The --noout flag suppresses the document echo, leaving only validation errors in the output. A clean exit with no output means the document is valid. xmllint is part of the libxml2 package, available on Linux via apt-get install libxml2-utils and on macOS via Homebrew with brew install libxml2. For Windows, it is included with many XML toolkits.

The most frequent XSD errors are: missing required elements (an element declared with minOccurs='1' is absent), type mismatches (a string in a field declared as xs:integer), pattern violations (a value that does not match an xs:pattern restriction), unexpected element order (elements declared in a specific sequence appearing out of order), and attribute violations (a required attribute is missing or an undeclared attribute is present). Most validators report these with the element path and constraint name.

Yes. Large XML schemas are often split across multiple XSD files using xs:import and xs:include directives. The root XSD imports the sub-schemas, and a validating parser resolves them either from the file system or from namespace URIs. When validating locally with xmllint or a Java-based validator (Xerces, Saxon), you pass the root XSD and the parser follows the import chain automatically, provided all referenced schema files are accessible.

xs:include pulls in a schema file that belongs to the same target namespace as the current schema. xs:import pulls in a schema file that belongs to a different namespace. Use xs:include to split a large schema into manageable files that all share one namespace. Use xs:import when you need to reference elements or types from an external namespace, such as the SOAP envelope namespace or a shared enterprise data model namespace.

For new projects using REST APIs and JSON payloads, JSON Schema is the practical choice — it has better tooling integration with OpenAPI, a lighter syntax, and broader library support in modern languages. XSD remains the right choice when working with SOAP web services, EDI formats like UBL and EDIFACT, government and healthcare data exchange (HL7 CDA, FHIR XML), or any legacy system that is already XML-based. If the ecosystem you are integrating with uses XML, XSD is the validation standard.

ShareXLinkedIn

Related articles