UP PREVIOUS NEXT   Technologies Internet et Education, © TECFA
  2. Document Object Model (DOM ) définition

2. Document Object Model (DOM ) définition

Le Modèle Objet de Document (DOM) est une interface de programmation d'application (API) pour des documents HTML valides et XML bien-formés. Il définit la structure logique d'un document (au sens large tu terme!) et la manière d'y accéder et de le manipuler.

Avec le DOM, les programmeurs peuvent construire des documents, naviguer dans leur structure ainsi qu'ajouter, modifier ou effacer des éléments et leur contenu. Tout ce qui se trouve dans un document HTML, ou XML, peut être touché, modifié effacé ou ajouté en utilisant le Modèle Objet de Document, à quelques exceptions près...

l'API DOM de PhP qui ressemble à celui d'autres langages de programmation qui implémentent DOM level 2 défini par le W3C.

Il existe 3 classes principales qu'on introduira dans la suite:

Il existe 12 autres classes ....

2.1 Le modèle de structure du DOM

Le contenu d'un arbre XML

Eléments supplémentaires:

2.2 Petite présentation des classes principales

A. La classe DOMDocument

Voici l'essentiel (Il existe pleins d'autres methodes et propriétés !):

Création d'un objet DOM

new DOMDocument ()

ex: $doc = new DOMDocument();

Remplir un objet DOM à partir d'une chaîne de caractères

DOMDocument->loadXML()

ex: $dom->loadXML("<?xml version=\"1.0\?> <hello> </hello> ?>");

Remplir un objet DOM à partir d'un fichier

DOMDocument->load()

ex: $dom->load("test.xml");

 

DOMDocument étend la classe DOMNode
(autrement hérite de ses attributs et méthodes présentés ci-dessous).

B. La classe "DomNode"

DOMNode représente un noeud (toutes les sortes) dans l'arbre du document.

Utilité de la classe DomNode

  • tester et extraire nom, valeur et type d'élément (genre "balise", "commentaire", "CDATA (texte)",
  • extraire ou modifier ses composants (noeds et attributs).

Quelques Propriétés:

  • nodeName = le nom du noeud

$el = .... // $el contien un noeud XML

$el->nodeName; // retourne son nom

  • nodeValue = contenu (si c'est un text node)
  • nodeType = parmi une liste des types de constantes qui définit le type d'objet qui est le noeud
  • attributes = donne les attributs
  • childNodes = donne une DOMNodeList d'éléments

Quelques Méthodes:

  • hasChildNodes() = indique s'il existe des nodes enfants
  • hasAttributes() = indique s'il existe des attributs

if ($el->hasAttributes()) echo "super, on a des attributs"

C. La classe DomElement

Quelques Propriétés:

  • tagName = le nom de la balise (identique à nodeName hérité)

Quelques Méthodes:

  • getElementsByTagName() = retourne une liste d'éléments

 

$exercise = ... // $exercise est un node de type DOMElement

$exercise->getElementsByTagName("staf");
// retourne la liste d'élément "stafs"

 

  • getAttribute() - Returns value d'un attribut

$exercice->getAttribute("id"); // retourne la valeur de l'attribut id

 

D. Les NodeList

 

$doc = new DOMDocument();

$doc->load("travaux.xml") or die("*** There is no such file ***");

$student_list = $doc->getElementsByTagName('student');

$student = $student_list->item(0);

 

 

$exercises = $student->getElementsByTagName('exercise');

foreach ($exercises as $exercise) {

$staf = $exercise->getElementsByTagName("staf")

...

}

 

foreach ($NodeList as $Noeud) { ..... }

C.f. le manuel pour une définition de foreach. C'est la seule façon de faire, oubliez les autres boucles !!

Exemple 2-1: Extraction des attributs

 
 
<?php 
 
$doc = new DOMDocument();
$doc->load("test.xml") or die("*** There is no such file ***");
 
$nodelist = $doc->getElementsByTagName
("para");
 
foreach ($nodelist as $node) {
  $content = $node->nodeValue;
  $id = $node->getAttribute('id')
;
  printf("ID = %s : %s <p>", $id, $content); 
}
?>

Exemple 2-2: Extraction des éléments et attributs d'un arbre

 

Copiez ces fonctions pour debugger votre code (ou faites mieux !)

 
function debug_node_list ($list
, $infos) {
  echo "<br>This list has " . $list->length
 . " elements\n";
  if (count($list) == 0) echo "<br>This list seems to be empty\n";
  else {
    echo "<ol>\n";
    foreach ($list as $el)
 {
      echo "<li>\n"; debug_element_rec
 ($el,""); echo "</li>\n";
    }
    echo "</ol>\n"; }
 }
 
function debug_element_rec ($el,$info) {
  $nodeType = $el->nodeType;
  echo "<br> Node Type = " . $nodeType . "\n";
 // ici on va faire des choses en fonction du type de noeud
 // (il en manquent certains ... comme les PI ou les entités)
  switch ($nodeType) {
  case XML_TEXT_NODE:
 {
    echo "<br>Node Value =" . $el->nodeValue;
    break;
  }
 
  case XML_ELEMENT_NODE: {
    echo "<br>Element Name =" . $el->nodeName;
    break;
  }
  case XML_ATTRIBUTE_NODE: {
    echo "<br>Attribute Name =" . $el->nodeName;
    break;
  }
  default:
    echo "<br>Strange Node !!! TYPE of element = " . gettype($el) . "\n";
  }
  if ($el->hasAttributes()) {
   echo "<br>Attributes: ";
   foreach ($el->attributes as $attr) {
     echo "[ " . $attr->name . " = " . $attr->value . " ]\n";
   } 
  }
  if ($el->hasChildNodes()) {
    debug_node_list ($el->childNodes, "Children of " . $el->nodeName);
  } }
 
// ici on charge une fichier XML et on lance la fonction ci-dessus
 
$doc = new DOMDocument();
$doc->load("travaux.xml") or die("*** There is no such file ***");
# show a few things
debug_node_list ($student_list
,"The tree");

Exemple 2-3: (complet) Extraction des travaux staf14 d'un étudiant staf-g

// *********************************** Aux functions
 
function get_value_of_first_named_child
 ($el, $child_name) {
  // debug_element ($el, "get_first_element for " . $child_name);
  $liste = $el->getElementsByTagName($child_name);
  return $liste->item(0)->nodeValue;
}
 
// ********************************** Main program
# create DOM object (DOMDocument class) and load xml
$doc = new DOMDocument();
$doc->load("travaux.xml") or die("*** There is no such file ***");
 
# get student nodes
$student_list = $doc->getElementsByTagName('student');
$student      = $student_list->item(0)
;
 
 
 
 
 
 
if ($student->nodeType == XML_ELEMENT_NODE) {
 
# get some data from personal-data
  $first_name    = get_value_of_first_named_child ($student, 'first-name');
  $family_name   = get_value_of_first_named_child ($student, 'family-name');
  // a less elegant way to do it :)
  $home_url_L    = $student->getElementsByTagName('home-url');
  $home_url      = $home_url_L->item(0)->nodeValue;
    
    // echo this information
    echo "<h2><a href='$home_url'>". $first_name . " " . $family_name . "</a></h2>\n";
    
    // get the student's list of exercices
 
    $exercises = $student->getElementsByTagName('exercise');
 
    // extract staf-14 exercises, should rather be done with xpath
    foreach ($exercises as $exercise) {
      $staf      = $exercise->getElementsByTagName("staf")->item(0);
      $attr_staf = $staf->getAttribute("no");
      $attr_no   = $staf->getAttribute("ex-number");
      $title     = get_value_of_first_named_child($exercise,"title");
      $url       = get_value_of_first_named_child($exercise,"url");
      if ($attr_staf == "14") {
	echo "<b>Staf14-ex".$attr_no.": </b> <a href='".$url."'>".$title."</a><br>\n";}
    }
}

UP PREVIOUS NEXT -- TIE