XML Well-Formed vs Schema-Valid: What Validators Actually Check
Your XML parser throws an error, but you're not sure if it's a syntax issue or a schema validation problem. Understanding the difference between well-formed XML and schema-valid XML is crucial for debugging XML processing, API integrations, and configuration files. This guide explains what each type of validation checks and how to identify common errors.
Well-Formed XML: Basic Syntax Rules
Well-formed XML means the document follows the fundamental XML syntax rules. Any XML parser can check this without needing a schema.
A well-formed XML document must:
- Have a single root element
- Properly nest all elements
- Close all tags
- Quote all attribute values
- Use valid character encoding
- Escape special characters in text content
Example: Well-Formed XML
<?xml version="1.0" encoding="UTF-8"?>
<order>
<customer id="12345">
<name>John Doe</name>
<email>john@example.com</email>
</customer>
<items>
<item sku="ABC-001" quantity="2">Widget A</item>
<item sku="XYZ-999" quantity="1">Widget B</item>
</items>
<total>49.99</total>
</order>This XML is well-formed because it follows all syntax rules: single root, proper nesting, closed tags, quoted attributes.
Example: NOT Well-Formed XML
<?xml version="1.0" encoding="UTF-8"?>
<order>
<customer id=12345>
<name>John Doe
<email>john@example.com</email>
</customer>
<items>
<item sku="ABC-001" quantity="2">Widget A</item>
</order>
</items>This XML has multiple well-formedness errors:
id=12345- attribute value not quoted (should beid="12345")<name>John Doe- unclosed tag (missing</name>)- Improper nesting - tags closed in wrong order
Use XML Validator to check if your XML is well-formed. The validator will catch these syntax errors immediately.
Schema-Valid XML: Business Rules Validation
Schema-valid XML means the document follows the rules defined in an XML Schema (XSD). A document can be well-formed but NOT schema-valid.
Schema validation checks:
- Element structure - required elements, element order, allowed children
- Data types - integers, dates, enums, patterns (regex)
- Cardinality - min/max occurrences of elements
- Attributes - required attributes, allowed values
- Namespaces - proper namespace declarations and usage
- Constraints - uniqueness, key references
Example: XSD Schema
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="order">
<xs:complexType>
<xs:sequence>
<xs:element name="customer" type="customerType"/>
<xs:element name="items" type="itemsType"/>
<xs:element name="total" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="orderId" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:complexType name="customerType">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="email" type="emailType"/>
</xs:sequence>
<xs:attribute name="id" type="xs:positiveInteger" use="required"/>
</xs:complexType>
<xs:simpleType name="emailType">
<xs:restriction base="xs:string">
<xs:pattern value="[^@]+@[^@]+\.[^@]+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="itemsType">
<xs:sequence>
<xs:element name="item" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="sku" type="xs:string" use="required"/>
<xs:attribute name="quantity" type="xs:positiveInteger" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>Example: Valid Against Schema
<?xml version="1.0" encoding="UTF-8"?>
<order orderId="ORD-2026-001">
<customer id="12345">
<name>John Doe</name>
<email>john@example.com</email>
</customer>
<items>
<item sku="ABC-001" quantity="2">Widget A</item>
<item sku="XYZ-999" quantity="1">Widget B</item>
</items>
<total>49.99</total>
</order>This XML is both well-formed and schema-valid because it matches the XSD rules:
- Has required attribute: orderId on root element
- Elements in correct order: customer, items, total
- Email matches pattern (has @ and .)
- All numeric fields are positive integers or decimals
- At least one item element exists
Example: NOT Valid Against Schema (But Well-Formed)
<?xml version="1.0" encoding="UTF-8"?>
<order>
<customer id="-500">
<name>John Doe</name>
<email>invalid-email</email>
</customer>
<items>
<!-- No items! -->
</items>
<total>not-a-number</total>
</order>This XML is well-formed (valid syntax) but NOT schema-valid because:
- Missing required attribute:
orderIdon root element - Invalid customer ID:
-500is not a positive integer - Invalid email:
invalid-emaildoesn't match email pattern - No items:
minOccurs="1"requires at least one item - Invalid total:
not-a-numberis not a decimal
Use XML/XSD Validator to validate XML against an XSD schema. This server-side tool performs full schema validation with detailed error messages.
Common Validation Errors Explained
Well-Formedness Errors
Unclosed Tags
<!-- ERROR: Missing closing tag -->
<customer>
<name>John Doe
</customer>
<!-- FIX: Close all tags -->
<customer>
<name>John Doe</name>
</customer>Unquoted Attributes
<!-- ERROR: Attribute values must be quoted -->
<item id=123 name=Widget>
<!-- FIX: Quote all attribute values -->
<item id="123" name="Widget">Improper Nesting
<!-- ERROR: Tags must close in reverse order -->
<outer>
<inner>Content</outer>
</inner>
<!-- FIX: Proper nesting -->
<outer>
<inner>Content</inner>
</outer>Special Characters Not Escaped
<!-- ERROR: < and & must be escaped -->
<description>Price: 5 < 10 & condition is true</description>
<!-- FIX: Use entity references -->
<description>Price: 5 < 10 & condition is true</description>
<!-- OR: Use CDATA section -->
<description><![CDATA[Price: 5 < 10 & condition is true]]></description>Schema Validation Errors
Missing Required Element
<!-- XSD requires email element -->
<xs:element name="email" minOccurs="1"/>
<!-- ERROR: Missing required element -->
<customer>
<name>John Doe</name>
</customer>
<!-- FIX: Include required element -->
<customer>
<name>John Doe</name>
<email>john@example.com</email>
</customer>Wrong Data Type
<!-- XSD expects integer -->
<xs:element name="quantity" type="xs:integer"/>
<!-- ERROR: Text instead of number -->
<quantity>five</quantity>
<!-- FIX: Use numeric value -->
<quantity>5</quantity>Elements in Wrong Order
<!-- XSD defines sequence: name, email, phone -->
<xs:sequence>
<xs:element name="name"/>
<xs:element name="email"/>
<xs:element name="phone"/>
</xs:sequence>
<!-- ERROR: Wrong order -->
<customer>
<email>john@example.com</email>
<name>John Doe</name>
<phone>555-0100</phone>
</customer>
<!-- FIX: Follow schema order -->
<customer>
<name>John Doe</name>
<email>john@example.com</email>
<phone>555-0100</phone>
</customer>Too Many Occurrences
<!-- XSD allows max 1 email -->
<xs:element name="email" maxOccurs="1"/>
<!-- ERROR: Multiple emails -->
<customer>
<name>John Doe</name>
<email>john@work.com</email>
<email>john@personal.com</email>
</customer>
<!-- FIX: Only one email -->
<customer>
<name>John Doe</name>
<email>john@work.com</email>
</customer>Invalid Attribute Value
<!-- XSD restricts status to enum -->
<xs:attribute name="status">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="pending"/>
<xs:enumeration value="approved"/>
<xs:enumeration value="rejected"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<!-- ERROR: Invalid enum value -->
<order status="processing">
<!-- FIX: Use valid enum value -->
<order status="pending">Namespace Validation
Namespaces are part of schema validation. If your XSD defines a target namespace, your XML must use that namespace correctly.
XSD with Target Namespace
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/order"
xmlns:ord="http://example.com/order"
elementFormDefault="qualified">
<xs:element name="order">
<!-- schema definition -->
</xs:element>
</xs:schema>XML Must Match Namespace
<!-- ERROR: Missing namespace -->
<order>
<customer id="123">
<name>John Doe</name>
</customer>
</order>
<!-- FIX: Include namespace declaration -->
<order xmlns="http://example.com/order">
<customer id="123">
<name>John Doe</name>
</customer>
</order>
<!-- OR: Use namespace prefix -->
<ord:order xmlns:ord="http://example.com/order">
<ord:customer id="123">
<ord:name>John Doe</ord:name>
</ord:customer>
</ord:order>Common namespace errors include missing namespace declarations, wrong namespace URIs, and incorrect use of prefixes. The XML/XSD Validator checks namespace validation as part of schema validation.
Validation Workflow: When to Check What
Step 1: Check Well-Formedness First
Always validate well-formedness before schema validation. If XML isn't well-formed, schema validation will fail with confusing errors.
# Quick check: Is this valid XML syntax?
# Use: XML Validator tool
1. Paste XML into validator
2. Check for syntax errors
3. Fix all well-formedness issues
4. Only then proceed to schema validationStep 2: Validate Against Schema
Once XML is well-formed, validate against XSD schema to check business rules and data types.
# Schema validation: Does XML match XSD rules?
# Use: XML/XSD Validator (server-side)
1. Paste XML into validator
2. Paste XSD schema
3. Run validation
4. Fix schema violations
5. Re-validate until no errorsStep 3: Debug Validation Errors
Read error messages carefully. Schema validators often provide line numbers and paths:
Error at line 5, column 10:
Element 'email': 'invalid-email' is not a valid value of the atomic type 'emailType'.
Translation:
- Line 5: <email>invalid-email</email>
- Problem: Value doesn't match email pattern in schema
- Fix: Use valid email formatReal-World Example: SOAP API Request
SOAP APIs use XML with strict schemas. Here's a realistic example showing the difference between well-formed and valid XML.
SOAP Schema (Simplified)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://api.example.com/payment"
xmlns:pay="http://api.example.com/payment">
<xs:element name="processPayment">
<xs:complexType>
<xs:sequence>
<xs:element name="amount" type="xs:decimal"/>
<xs:element name="currency" type="currencyCode"/>
<xs:element name="cardNumber" type="cardType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="currencyCode">
<xs:restriction base="xs:string">
<xs:enumeration value="USD"/>
<xs:enumeration value="EUR"/>
<xs:enumeration value="GBP"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="cardType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{16}"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>Well-Formed but NOT Valid Request
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<processPayment xmlns="http://api.example.com/payment">
<amount>abc</amount>
<currency>USD</currency>
<cardNumber>1234</cardNumber>
</processPayment>
</soap:Body>
</soap:Envelope>This request is well-formed (valid XML syntax) but schema validation fails:
amountis "abc" - not a decimal numbercardNumberis "1234" - doesn't match 16-digit pattern
Valid Request
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<processPayment xmlns="http://api.example.com/payment">
<amount>99.99</amount>
<currency>USD</currency>
<cardNumber>4111111111111111</cardNumber>
</processPayment>
</soap:Body>
</soap:Envelope>Now the request is both well-formed AND schema-valid:
- amount is a valid decimal
- currency is a valid enum value
- cardNumber matches 16-digit pattern
- Elements in correct order
- Namespaces properly declared
Quick Reference: Error Types
| Error Type | Validation Level | Example |
|---|---|---|
| Unclosed tag | Well-formedness | <name>John (missing </name>) |
| Unquoted attribute | Well-formedness | id=123 (should be id="123") |
| Improper nesting | Well-formedness | <a><b></a></b> |
| Invalid characters | Well-formedness | Unescaped < or & |
| Missing required element | Schema validation | <customer> without <email> |
| Wrong data type | Schema validation | <quantity>five</quantity> (expects integer) |
| Wrong element order | Schema validation | Elements not in sequence defined by XSD |
| Invalid enum value | Schema validation | status="invalid" (not in enum list) |
| Pattern mismatch | Schema validation | email="not-an-email" (doesn't match regex) |
| Cardinality violation | Schema validation | Too many or too few occurrences |
| Wrong namespace | Schema validation | Missing or incorrect namespace URI |
Tools for XML Validation
DevToys Pro provides two XML validation tools:
- XML Validator - Client-side well-formedness checking. Fast, instant feedback on syntax errors. Use this for quick checks of XML structure.
- XML/XSD Validator - Server-side schema validation. Validates XML against XSD schemas with detailed error messages. Use this for complete validation including business rules, data types, and namespaces.
Best Practices
- Validate early - Check well-formedness during development, not in production
- Use schemas - Define XSD schemas for APIs and config files
- Validate on both sides - Client validates before sending, server validates on receiving
- Provide clear errors - Include line numbers and element paths in error messages
- Test edge cases - Validate with empty values, special characters, boundary conditions
- Keep schemas updated - Version XSD schemas alongside API versions
Summary
Well-formed XML follows basic syntax rules (proper nesting, closed tags, quoted attributes). Any XML parser can check this.
Schema-valid XML follows business rules defined in an XSD schema (required elements, data types, order, cardinality, namespaces). Requires a validating parser with the schema.
A document can be well-formed but not valid. Always check well-formedness first, then schema validation.
Use XML Validator for syntax checks and XML/XSD Validator for complete schema validation.
Need to validate XML for SOAP APIs or configuration files? Try our XML Validator for quick syntax checks and XML/XSD Validator for complete schema validation with detailed error reporting.