L'extension DOM met à disposition plusieurs moyens de validation d'un document XML. Contrairement à ces prédécesseurs, PHP 5 introduit la validation par des schémas W3C ou Relax NG en plus de la validation traditionnelle par la définition de type du document (DTD).

//Inidique si le document doit être (true) 
//ou ne pas être (false) validé par sa DTD
$doc_xml->validateOnParse = true;
//Validation d'un document XML en fonction de sa DTD
$booleen = $doc_xml->validate();
//Valide un document XML en fonction 
//du fichier contenant le schéma XSD
$booleen = $doc_xml->schemaValidate('schema.xsd');
//Valide un document XML en fonction de
//la chaîne de caractères contenant le schéma XSD
$booleen = $doc_xml->schemaValidateSource($sourceXSD);
//Valide un document XML en fonction 
//du fichier contenant le schéma Relax NG
$booleen = $doc_xml->relaxNGValidate('schema.rng');
//Valide un document XML en fonction de
//la chaîne de caractères contenant le schéma XSD
$booleen = $doc_xml->relaxNGValidateSource($sourceRNG);

La validation par DTD nécessite que le document XML contienne au moins la déclaration DOCTYPE afin que ce document puisse être validé par la méthode validate() ou directement au chargement à l'aide de l'attribut validateOnParse.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Fichier : employes.xml -->
<!DOCTYPE employes SYSTEM "definition.dtd">
<employes>
  <!-- ... -->
</employes>

<?php
  $doc_xml = new DOMDocument();
  $doc_xml->validateOnParse = true;
  $doc_xml->load('employes.xml');
  if($doc_xml->validate();)
    echo 'Le document XML est valide';
?>

La méthode validate() permet de revalider le document XML suite à une modification de son arborescence.

La validation par des schémas W3C et Relax NG demande simplement de fournir :

  • soit le nom du fichier contenant le schéma XSD ou RNG,
  • soit la source textuelle contenant le schéma XSD ou RNG.
<?php
  $doc_xml = new DOMDocument();
  $doc_xml->load('source.xml');

  if($doc_xml->validateSchema('schema.xsd');)
    echo 'Le document XML est valide par rapport au schéma W3C';

  if($doc_xml->relaxNGValidate('schema.rng');)
    echo 'Le document XML est valide par rapport au schéma Relax NG';
?>

Si le document XML comporte déjà une déclaration de type de document, cela ne pose aucun problème pour tenter des validations avec d'autres schémas.

<php
  $fichier = 'employes';
  $doc_xml = new DOMDocument();
  $doc_xml->validateOnParse = true;
  if($doc_xml->load($fichier . '.xml')){
    echo '<h3>Le document XML ' 
          . $employe . 
          'n\'a été chargé !</h3>';
    if($doc_xml->validate())
      echo '<p>Le document XML est valide '
         . 'par rapport à la DTD</p>';

    if($doc_xml->schemaValidate($fichier . '.xsd'))
      echo '<p>Le document XML est valide '
         . 'par rapport au schéma W3C</p>';
  
    if($doc_xml->relaxNGValidate($fichier . '.rng'))
      echo '<p>Le document XML est valide ' 
         . 'par rapport au schéma Relax NG</p>';
  }
  else 
    echo '<p style="color:red">Le document XML ' 
         . $employe . 
         'n\'a pu être chargé !</p>';
?>

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Fichier : employes.xml -->
<employes>
  <employe id="RJ1002" service="DG001">
    <nom>Robierre</nom>
    <prenom>Jean</prenom>
  </employe>
  <employe id="LA1012" service="DG001">
    <nom>Lardut</nom>
    <prenom>Anne</prenom>
  </employe>
  <employe id="GA1013" service="ST001">
    <nom>Guilde</nom>
    <prenom>Angélique</prenom>
  </employe>
  <employe id="HP1022" service="SC001">
    <nom>Henry</nom>
    <prenom>Paul</prenom>
  </employe>
  <employe id="MM1045" service="RH001">
    <nom>Mortier</nom>
    <prenom>Marc</prenom>
  </employe>
  <employe id="LS1102" service="SQ001">
    <nom>Lebreton</nom>
    <prenom>Sophie</prenom>
  </employe>
  <employe id="JM1095" service="RD001">
    <nom>Jolie</nom>
    <prenom>Martine</prenom>
  </employe>
  <employe id="MT1036" service="SC101">
    <nom>Marcelin</nom>
    <prenom>Tania</prenom>
  </employe>
  <employe id="LL1029" service="SC101">
    <nom>Léger</nom>
    <prenom>Laurence</prenom>
  </employe>
  <employe id="DM1052" service="SC001">
    <nom>Duroi</nom>
    <prenom>Maxime</prenom>
  </employe>
</employes>

<?xml version="1.0" encoding="UTF-8"?>
<!-- Fichier : definition.dtd -->
<!ELEMENT employe (nom, prenom)>
<!ATTLIST employe
           id ID #REQUIRED
           service NMTOKEN #REQUIRED
>
<!ELEMENT employes (employe+)>
<!ELEMENT nom (#PCDATA)>
<!ELEMENT prenom (#PCDATA)>

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Fichier : schema.xsd -->
<xsd:schema 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            elementFormDefault="qualified">
  <xsd:element name="employe">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="nom"/>
        <xsd:element ref="prenom"/>
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:ID" use="required"/>
      <xsd:attribute name="service" type="xsd:NMTOKEN" use="required"/>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="employes">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="employe" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="nom" type="xsd:string"/>
  <xsd:element name="prenom" type="xsd:string"/>
</xsd:schema>

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Fichier : schema.rng -->
<element 
            name="employes" 
            xmlns="http://relaxng.org/ns/structure/1.0"
            datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <oneOrMore>
    <element name="employe">
    <attribute name="id">
      <data type="ID"/>
    </attribute>
    <attribute name="service">
      <data type="NMTOKEN"/>
    </attribute>
      <element name="nom">
        <text/>
      </element>
      <element name="prenom">
        <text/>
      </element>
    </element>
  </oneOrMore>
</element>