Example 5: XSD Schemas

Validation with data types, something DTD can't check

🎯 What does this example cover?

Un XSD (XML Schema Definition) hace todo lo que un DTD, pero además exige tipos de datos: puedes decir que anio debe ser un número entero, no cualquier texto. El XSD de este ejemplo (que puedes ver más abajo) exige que <anio> sea xs:integer y que el atributo id también lo sea. Prueba las muestras para ver cómo PHP detecta, con DOMDocument::schemaValidateSource(), errores de tipo que un DTD no vería.

Choose or write a document

ℹ️ The XSD schema used
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="libro">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="titulo" type="xs:string"/>
        <xs:element name="autor" type="xs:string"/>
        <xs:element name="anio" type="xs:integer"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:integer" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

Validation result

✅ XML válido según el XSD Structure and data types are correct.

Validated document

<?xml version="1.0"?>
<libro id="1">
    <titulo>El Quijote</titulo>
    <autor>Miguel de Cervantes</autor>
    <anio>1605</anio>
</libro>

📖 Code Explanation

Complete PHP Code

<?php
libxml_use_internal_errors(true);

$dom = new DOMDocument();
$dom->loadXML($xmlDocumento);

$esValido = $dom->schemaValidateSource($xsd);

if (!$esValido) {
    foreach (libxml_get_errors() as $error) {
        echo $error->message;
    }
}
?>

📝 Data types in the XSD

<xs:element name="anio" type="xs:integer"/>

What does it do? Declares that the content of <anio> must be interpretable as an integer. If you enter non-numeric text, validation fails — something a DTD can't check, since it only understands generic text (#PCDATA).

💡 Concept: XSD vs DTD

XSD is written in XML (more verbose, but more expressive) and supports types, ranges, patterns (regex) and namespaces. DTD is simpler but more limited.

📝 schemaValidateSource()

$dom->schemaValidateSource($xsd);

What does it do? Validates the document already loaded in $dom against an XSD schema provided as a text string. There's also schemaValidate($rutaArchivo) if the XSD is in a separate file.

🎯 Key Concepts Learned

XSD

  • Written in XML syntax
  • Supports data types (integer, string, date...)
  • More expressive and detailed than DTD

Type Validation

  • Detects values with the wrong type
  • Applies to both elements and attributes
  • Fails during validation, not parsing

PHP and XSD

  • schemaValidateSource() with XSD as text
  • schemaValidate() with XSD in a file
  • libxml_get_errors() for the details

💪 Practical Exercise

Explore the limits of typing

  1. Try the 4 samples and compare the error messages with those from the DTD example
  2. Write an XML with a negative anio (for example, -100). Does the current XSD reject it? Should it?
  3. Think about which XSD type you'd use to validate an email or a postal code (hint: xs:pattern with a regular expression)

Restrict years to a reasonable range

<xs:element name="anio">
    <xs:simpleType>
        <xs:restriction base="xs:integer">
            <xs:minInclusive value="0"/>
            <xs:maxInclusive value="2100"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

xs:integer on its own accepts negatives; with xs:restriction we add specific limits.