Ejemplo 4: Validación con DTD
Define reglas de estructura para tu XML y valida documentos contra ellas
🎯 ¿En qué consiste este ejemplo?
Un DTD (Document Type Definition) declara qué elementos puede tener un
documento XML, en qué orden y con qué atributos obligatorios. Este ejemplo usa una DTD fija
(la puedes ver más abajo) que exige un <libro> con id
obligatorio y, en este orden exacto, titulo, autor y anio.
Elige una muestra o escribe tu propio XML, y PHP lo validará de verdad contra esa DTD usando
DOMDocument::validate().
Elige o escribe un documento
Resultado de la validación
Documento enviado a validar
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE libro [
<!ELEMENT libro (titulo, autor, anio)>
<!ATTLIST libro id CDATA #REQUIRED>
<!ELEMENT titulo (#PCDATA)>
<!ELEMENT autor (#PCDATA)>
<!ELEMENT anio (#PCDATA)>
]>
<libro id="001">
<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($xmlConDtd);
$esValido = $dom->validate();
if (!$esValido) {
foreach (libxml_get_errors() as $error) {
echo $error->message;
}
}
?>
📝 La propia DTD
<!ATTLIST libro id CDATA #REQUIRED>
¿Qué hace? <!ELEMENT> declara que <libro> debe contener, en ese orden exacto, titulo, autor y anio. <!ATTLIST> declara que el atributo id es obligatorio (#REQUIRED).
💡 Concepto: contrato de estructura
Una DTD es un "contrato": cualquier XML que la use debe cumplirlo exactamente, incluido el orden de los elementos, algo que las tres muestras inválidas de este ejemplo incumplen a propósito.
📝 Validar con PHP
¿Qué hace? Comprueba el documento cargado contra la DTD referenciada en su <!DOCTYPE> y devuelve true o false. Con libxml_use_internal_errors(true) los errores no se muestran directamente sino que se pueden recoger con libxml_get_errors().
🎯 Conceptos Clave Aprendidos
DTD
- Define elementos, orden y atributos permitidos
- Usa su propia sintaxis, no XML
- Puede ser interna (
<!DOCTYPE ... [ ]>) o externa
Validación en PHP
DOMDocument::validate()libxml_use_internal_errors()para capturar erroreslibxml_get_errors()lista los problemas
Bien formado vs. válido
- "Bien formado": sintaxis XML correcta
- "Válido": además, cumple una DTD/XSD
- Un XML puede ser bien formado pero inválido
💪 Ejercicio Práctico
Rompe y arregla la validación
- Prueba las 4 muestras y lee el mensaje de error exacto que da libxml en cada caso
- Escribe en el editor un
<libro>con un elemento repetido (por ejemplo, dos<titulo>) y observa el resultado - Modifica mentalmente la DTD para que
aniosea opcional. ¿Qué símbolo de DTD usarías? (pista:?,*o+)
Hacer "anio" opcional
<!ELEMENT libro (titulo, autor, anio?)>
El símbolo ? significa "0 o 1 veces". * sería "0 o más" y + "1 o más".