DOMDocument
, DOMElement
,
DOMText
DOMDocument
,DOMDocument
.nodeType
(valeur : un nombre).nodeName
, qui
est plus explicite - mais il faut savoir l'interpréter !DOMDocument
, deux de ces
espèces méritent en priorité notre attention : DOMElement
et DOMText
.DOMDocument
DOMDocument
, le nodeType
vaut 9 et le nodeName
est la chaîne
constante #document
.DOMDocument
contient un DOMElement
particulier
qui est la racine de l'arbre XML.nodeType
= 7, nodeName
= xml-stylesheet
)nodeType
=
10, nodeName
= le nom de la
balise-racine) DOMElement
C'est
l'espèce des sommets
de
l'arbre qui correspondent aux balises dans le texte XML.nodeType
correspondant vaut 1, et
le nodeName
est le nom de la balise.DOMElement
possède un nom
(tagName
, celui de la balise),
des attributs et des enfants.DOMDocument
contient un DOMElement
particulier
qui est la racine de l'arbre XML. DOMText
nodeType
correspondant vaut 1.DOMText
sera toujours enfant d'un DOMElement
,
tandis que lui-même
n'aura ni attribut ni enfant, Voiture.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="Voiture.css"?>
<!DOCTYPE Voiture SYSTEM "Voiture.dtd" >
<Voiture marque="Renault" modèle="Safrane">
<Carosserie couleur="rouge">
<Capot>Un peu
cabossé</Capot>
</Carosserie>
<Moteur>
<Cylindres />
<Allumage>Défectueux</Allumage>
</Moteur>
<Transmission type="automatique"
nb_vitesses="5">
<Boîte />
<TrainAV />
<TrainAR />
</Transmission>
</Voiture>
DOMDocument
, 10 DOMElement
s
et 2 DOMText
s.DOMDocument
.DOMDocument
vide, et on y charge le contenu d'un fichier :$doc = new DOMDocument();
$doc->load("Voiture.xml");
loadXML(la_chaîne)
.echo
"$doc->nodeType:$doc->nodeName\n";
//
nodeType
et nodeName
sont
en PHP des attributs, on les interroge donc sans parenthèses
$top = $doc->childNodes; //
idem
foreach ( $top as $enf ){
echo "$enf->nodeType:$enf->nodeName
- ";
}
9:#document
7:xml-stylesheet - 10:Voiture - 1:Voiture -
getDocumentElement()
qui livre l'Element
-racine n'existe pas en PHP.my $voiture = $doc->getDocumentElement();
$voiture =
$doc->lastChild;
Document
sont
placés avant l'arbre XML).echo "$voiture->nodeType:$
voiture
->nodeName\n";
1:Voiture
DOMElement
.getAttribute(le-nom)
$marque = $voiture->getAttribute("marque");
$modele = $voiture->
getAttribute("mode
le");
"mode
le"
,
pas comme en Perl "mod\x{00E8}le
"
echo "$marque $modele\n"
;
Renault Safrane
childNodes
$cmt = $voiture->childNodes;
foreach ( $cmt as
$enf
){
echo "$enf->nodeType:$enf->nodeName
- ";
}
childNodes
nous donne tous
les enfants du DOMElement
concerné.DOMElement
est entouré
par deux objets DOMText.
La boucle ci-dessus donne :3:#text - 1:Carosserie -
3:#text - 1:Moteur - 3:#text -
1:Transmission - 3:#text -
DOMText
.DOMText
n'est pas une
chaîne de caractères !DOMText
est une "boîte" qui contient une
chaîne.wholeText
pour avoir
la chaîne elle-même.DOMElement
ne contenant
que du texte (comme Capot
et Allumage
dans
l'exemple ci-dessus)DOMText
est alors son unique enfant,
on
l'obtient
directement par l'attribut firstChild
.$carosserie = $cmt->item(1); // après le
#text dû à l'indentation
$cmt
est
une DOMNodeList
, pas un banal tableau.foreach
, mais
non pas l'indexer
directement par $cmt[i]
$cmt->item(1)
.
$caps = $carosserie->childNodes;
foreach ( $caps as $enf ){
echo "$enf->nodeType:$enf->nodeName
- ";
}
3:#text - 1:Capot -
3:#text -
$capot = $caps->item(1); // idem
$txt = $capot->firstChild; // capot est une feuille
echo "$txt->nodeType:$txt->nodeName: \"$txt->wholeText\"\n";
3:#text: "Un peu cabossé"
voiture1.php
<?php
$doc = new DOMDocument();
$doc->load("Voiture.xml");
echo "$doc->nodeType:$doc->nodeName\n";
$top = $doc->childNodes;
foreach ( $top as $enf ){
echo "$enf->nodeType:$enf->nodeName
- ";
}
echo "\n";
$voiture = $doc->lastChild;
echo "$voiture->nodeType:$voiture->nodeName\n";
$marque = $voiture->getAttribute("marque");
$modele = $voiture->getAttribute("modele");
echo "$marque $modele\n";
$cmt = $voiture->childNodes;
foreach ( $cmt as $enf ){
echo "$enf->nodeType:$enf->nodeName
- ";
}
echo "\n";
$carosserie = $cmt->item(1);
$caps = $carosserie->childNodes;
foreach ( $caps as $enf ){
echo "$enf->nodeType:$enf->nodeName
- ";
}
echo "\n";
$capot = $caps->item(1); // idem
$txt = $capot->firstChild; // capot est une feuille
echo "$txt->nodeType:$txt->nodeName:
\"$txt->wholeText\"\n";
?>
jfp% php voiture1.php
9:#document
7:xml-stylesheet - 10:Voiture - 1:Voiture -
1:Voiture
Renault Safrane
3:#text - 1:Carosserie - 3:#text - 1:Moteur - 3:#text - 1:Transmission
- 3:#text -
3:#text - 1:Capot - 3:#text -
3:#text: "Un peu cabossé"
jfp%
DOMNode
DOMDocument
, DOMElement
et DOMText
appartiennent toutes au même
genre,
appelé DOMNode
.DOMNode
DOMDocument
,
DOMElement
ou DOMText
.nodeType
(valeur
: un nombre entier), nodeName
(valeur
: chaîne) firstChild
, lastChild
(valeur : un objet de genre DOMNode
)childNodes
(valeur une DOMNodeList
,
sorte de tableau d'objets qui sont tous du genre DOMNode
)
, DOMNode
.wholeText
est spécifique à DOMText
getAttribute()
est
spécifique à DOMElement
.Node
, contenant aussi bien des Element
que des Text
.Element
et à un Text
!wholeTetxt
à un Element
,
ni getAttribute(...)
à un Text
...childNodes
) d'un DOMElement
,
et traiter chacun selon son espèce.DOMNode
,
il faut donc lui demander son nodeType
pour savoir quoi
faire...
Voici un exemple de parcours récursif d'un DOMDocument
(fichier parcours.php
).<?php
// un parcours générique
function parcours($nd){ // l'argument $nd est un DOMNode
switch( $nd->nodeType ){
case 9 : { //DOMDocument
echo "Le
document\n";
foreach(
$nd->childNodes as $n ){
parcours($n);
}
break;
}
case 7 ; { //
DOMProcessingInstruction (feuille de style)
echo "La
feuille de style\n";
break;
}
case 10 : { // DOMDocumentType
(DTD)
echo "La DTD,
de racine $nd->name, chemin : $nd->systemId\n";
break;
}
case 1 : { // DOMElement
echo
"$nd->tagName";
foreach(
$nd->attributes as $na => $vala ){
echo " $na=\"$vala->value\"";
}
echo "\n";
foreach(
$nd->childNodes as $n ){
parcours($n);
}
break;
}
case 3 : { // texte : on
n'imprime pas les textes "parasites" à contenu blanc
$chn =
$nd->wholeText;
if(
!preg_match('/^\s+$/', $chn) ){
echo "Texte : \"$chn \"\n";
}
break;
}
default : echo "Objet de type
inconnu : $nd->nodeType\n";
}
}//parcours
$doc = new DOMDocument();
$doc->load("Voiture/Voiture.xml");
parcours($doc);
?>
jfp% php parcours.php
Le document
La feuille de style
La DTD, de racine Voiture, chemin : Voiture.dtd
Voiture marque="Renault" modele="Safrane"
Carosserie couleur="rouge"
Capot
Texte : "Un peu cabossé "
Moteur
Cylindres
Allumage
Texte : "Défectueux "
Transmission type="automatique" nb_vitesses="5"
Boite
TrainAV
TrainAR
getElementsByTagName(un-nom)
Element
s
:Element
ou à un Document
,
getElementsByTagName(un-nom)
va renvoyer DOMElement
s et
portent le nom
passé en paramètre DOMElement
s
de
même nom sont tous des successeurs d'un même sommet,getChildNodes
,
et à un parcours attentif à la nature des enfants,Utilisation de getElementsByTagName(...)
sur des
documents bien structurés.
Ex1.xml
<?xml version="1.0" encoding="UTF-8"?>
<liste>
<eleve nom="Hélène" note="16"/>
<eleve nom="Pierre" note="12"/>
<eleve nom="Joëlle" note="15"/>
<eleve nom="Paul" note="13"/>
<eleve nom="Françoise" note="19"/>
<eleve nom="Jacques" note="17"/>
</liste>
Lire_1.php
<?php
/* Lire des Noms-Notes en format 1 */
function lire_1($doc){
$depart = $doc->lastChild;
$k = 0; //nombre de notes
$s = 0; //le total
$les_eleves =
$depart->getElementsByTagName("eleve");
foreach( $les_eleves as $l_eleve ){ // foreach
marche avec NodeList !
$le_nom =
$l_eleve->getAttribute("nom");
$la_note =
$l_eleve->getAttribute("note");
echo "$le_nom a pour note
$la_note\n";
$s += $la_note;
$k++;
}
if( $k == 0 ){
die("fichier vide");
}else{
return $s/$k;
}
}// lire_1
function lecture ($fichIn){
$doc = new DOMDocument();
$doc->load($fichIn);
$moy = lire_1($doc);
echo "\nMoyenne : $moy\n";
}//lecture
lecture("Ex1.xml");
?>
jfp% php Lire_1.php
Hélène a pour note 16
Pierre a pour note 12
Joëlle a pour note 15
Paul a pour note 13
Françoise a pour note 19
Jacques a pour note 17
Moyenne : 15.3333333333
Ex2.xml
<?xml version="1.0" ?>
<liste>
<eleve>
<nom>
Toto</nom> <note> 12
</note>
</eleve>
<eleve>
<nom>
Tata</nom> <note> 13
</note>
</eleve>
<eleve>
<nom>
Tutu</nom> <note> 17
</note>
</eleve>
</liste>
Lire_2.php
<?php
/* Noms-Notes en format 2 */
function lire_2($doc){
$depart = $doc->lastChild;
$k = 0; //nombre de notes
$s = 0; //le total
$les_eleves =
$depart->getElementsByTagName("eleve");
foreach( $les_eleves as $l_eleve ){
$elt_nom =
$l_eleve->getElementsByTagName("nom")->item(0);
$elt_note =
$l_eleve->getElementsByTagName("note")->item(0);
$le_nom =
$elt_nom->firstChild->wholeText;
$la_note =
$elt_note->firstChild->wholeText;
echo "$le_nom a pour note
$la_note\n";
$s += $la_note;
$k++;
}
if( $k == 0 ){
die("fichier vide");
}else{
return $s/$k;
}
}// lire_1
function lecture ($fichIn){
$doc = new DOMDocument();
$doc->load($fichIn);
$moy = lire_2($doc);
echo "\nMoyenne : $moy\n";
}//lecture
lecture("Ex2.xml");
?>
fp% php Lire_2.php Ex2.xml
Toto a pour note 12
Tata a pour note 13
Tutu a pour note 17
Moyenne : 14
jfp%