Ejemplo 5: Esquemas XSD

Validación con tipos de datos, algo que DTD no puede comprobar

🎯 ¿En qué consiste este ejemplo?

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.

Elige o escribe un documento

ℹ️ El esquema XSD usado
<?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>

Resultado de la validación

✅ XML válido según el XSD Estructura y tipos de datos correctos.

Documento validado

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

📖 Explicación del Código

Código PHP Completo

<?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;
    }
}
?>

📝 Tipos de datos en el XSD

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

¿Qué hace? Declara que el contenido de <anio> debe poder interpretarse como un número entero. Si escribes texto no numérico, la validación falla, algo que un DTD no puede comprobar porque solo entiende texto genérico (#PCDATA).

💡 Concepto: XSD vs DTD

XSD está escrito en XML (más verboso, pero más expresivo) y soporta tipos, rangos, patrones (regex) y espacios de nombres. DTD es más simple pero más limitado.

📝 schemaValidateSource()

$dom->schemaValidateSource($xsd);

¿Qué hace? Valida el documento ya cargado en $dom contra un esquema XSD proporcionado como cadena de texto. Existe también schemaValidate($rutaArchivo) si el XSD está en un archivo aparte.

🎯 Conceptos Clave Aprendidos

XSD

  • Escrito en sintaxis XML
  • Soporta tipos de datos (integer, string, date...)
  • Más expresivo y detallado que DTD

Validación de tipos

  • Detecta valores con el tipo incorrecto
  • Aplica tanto a elementos como a atributos
  • Falla en la validación, no al parsear

PHP y XSD

  • schemaValidateSource() con XSD en texto
  • schemaValidate() con XSD en archivo
  • libxml_get_errors() para el detalle

💪 Ejercicio Práctico

Explora los límites del tipado

  1. Prueba las 4 muestras y compara los mensajes de error con los del ejemplo de DTD
  2. Escribe un XML con anio negativo (por ejemplo, -100). ¿El XSD actual lo rechaza? ¿Debería?
  3. Piensa qué tipo XSD usarías para validar un email o un código postal (pista: xs:pattern con una expresión regular)

Restringir años a un rango razonable

<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 por sí solo acepta negativos; con xs:restriction añadimos límites concretos.