Un document XML peut nécessiter une mise à jour de sa structure et de ses données. Le DOM dispose de méthodes capables de remplacer et de supprimer des noeuds et de modifier des données textuelles.

La méthode removeChild() de l'objet DOMNode supprime le noeud spécifié de la liste des enfants.

$doc_xml = new DOMDocument();
$doc_xml->validateOnParse = true;
$doc_xml->loadXML($source); //voir La création
$element = $doc_xml->getElementById('XSY210356');
$racine = $doc_xml->documentElement;
$noeud_sup = $racine->removeChild($element);

echo $doc_xml->saveXML();
/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
  </logiciel>
</liste>*/

De cette manière n'importe quel noeud dans l'arborescence XML peut être supprimé. Pour un noeud textuel, il suffit de cibler l'objet contenant le texte, puis de soumettre l'enfant de ce dernier à la méthode removeChild().

$commentaires = $doc_xml->getElementsByTagName('commentaire');
foreach($commentaires as $commentaire){
  $texte = $commentaire->childNodes->item(0);
  $commentaire->removeChild($texte);
}

/*Tous les éléments commentaire
deviennent des éléments vides <commentaire/>
*/

Après suppression un noeud DOMElement peut devenir un élément vide.

for($i = $noeuds->length - 1; $i >= 0; $i--){
  $noeud = $noeuds->item($i);
  $noeud_sup = $element->removeChild($noeud);
  afficherInfos($noeud_sup);
}
/*L'arborescence de l'élément logiciel avec id="XSY210356"
devient un élément vide <logiciel id="XSY210356"/>
*/

La méthode removeChild() est susceptible de lancer deux exceptions :

  • DOM_NO_MODIFICATION_ALLOWED_ERR est lancée si le noeud est en lecture seul.
  • DOM_NOT_FOUND est lancés si le noeud à supprimer n'est pas un enfant de ce noeud.

Les attributs peuvent être supprimés d'un élément en utilisant les méthodes de suppression d'attributs de l'objet DOMElement.

$xpath = new DOMXPath($doc_xml);
$elements = $xpath->query(
                          '//logiciel[1]/nom', 
                          $doc_xml->documentElement);

$element = $elements->item(0);
if($element->removeAttribute('systeme_exploitation'))
  echo 'L\'attribut systeme_exploitation a été supprimé !';

$attribut = $element->attributes->item(0);
if($element->removeAttributeNode($attribut))
  echo 'L\'attribut ' . $attribut->nodeName . ' a été supprimé !';

echo $doc_xml->saveXML();
/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    <nom>Cooktop 2.200</nom>
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
  </logiciel>
  <logiciel id="XSY210356">
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
  </logiciel>
</liste>*/

Une autre méthode de suppression existe, mais elle doit être employée pour un attribut situé dans un espace de noms. Il s'agît de la méthode DOMElement->removeAttributeNS().

La méthode replaceChild() remplace un noeud par un autre.

xpath = new DOMXPath($doc_xml);
$elements = $xpath->query('//logiciel/commentaire');
$element1 = $elements->item(0);
$element2 = $elements->item($elements->length - 1);
$texte1 = $element1->firstChild->cloneNode();
$texte2 = $element2->firstChild->cloneNode();
$nouv_noeud1 = $element1->replaceChild(
                              $texte2, 
                              $element1->firstChild);
$nouv_noeud2 = $element2->replaceChild(
                              $texte1, 
                              $element2->firstChild);
echo $doc_xml->saveXML();
/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    ...
    <commentaire>
      Permet de creer des documents XML.
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
  </logiciel>
  <logiciel id="XSY210356">
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
    <commentaire>
      Un editeur XML, XSLT, XPath et DTD puissant et totalement gratuit.
    </commentaire>
  </logiciel>
    ...
</liste>*/

Cette méthode peut lancer plusieurs exceptions :

  • DOM_NO_MODIFICATION_ALLOWED_ERR est lancée si le noeud est en lecture seule ou si le parent précédent du noeud à insérer est en lecture seule.
  • DOM_HIERARCHY_REQUEST_ERR est lancée si le noeud est d'un type qui n'autorise pas les enfants du type du nouveau noeud, ou si le noeud à insérer est un des ancêtres de ce noeud ou ce noeud lui-même.
  • DOM_WRONG_DOCUMENT_ERR est lancée si le nouveau noeud provient d'un document différent que celui qui l'a créé.
  • DOM_NOT_FOUND est lancée si l'ancien noeud n'est pas un enfant de ce noeud.

Les chaînes de caractères présentes dans les noeuds textuels ou dans les attributs peuvent être modifiées complètement ou partiellement. La classe DOMCharacterData propose des méthodes de modification du contenu textuel d'un noeud.

$doc_xml->loadXML($source);
$logiciels = $doc_xml->getElementsByTagName('logiciel');
foreach($logiciels as $logiciel){
  $noms = $logiciel->getElementsByTagName('nom');
  $nom = $noms->item(0)->firstChild;
  $commentaires = $logiciel->getElementsByTagName('commentaire');
  $commentaire = $commentaires->item(0)->firstChild;
  //Insertion du nom devant le commentaire
  $commentaire->insertData(0, ' : ');
  $commentaire->insertData(0, $nom->nodeValue);
  $colprix = $logiciel->getElementsByTagName('prix');
  $prix = $colprix->item(0)->firstChild;
  $pos = strrpos($commentaire->nodeValue, '.');
  $taille = strlen($commentaire->nodeValue);
  //Suppression du point terminal et des espaces blancs
  $commentaire->deleteData($pos , $taille - $pos);
  //Ajout du prix entre parenthèses
  $commentaire->appendData('(');
  $commentaire->appendData($prix->nodeValue);
  $commentaire->appendData(').');
}

echo $doc_xml->saveXML();
/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    ...
    <commentaire>
      Cooktop 2.200
      : 
      Un editeur XML, XSLT, XPath et DTD puissant et totalement gratuit
      (00.00).
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
    <commentaire>
      XML Spy 4.1
      : 
      Un editeur XML desormais mature
      (199,00).
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XSY210356">
    ...
    <commentaire>
      XML Spy 4.1 B2B Server
     : 
      La version 4 en version Business to business
    (1 999,00).
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
    <commentaire>
      XMLwriter v1.21
      : 
      Permet de creer des documents XML
      (75,00).
    </commentaire>
    ...
  </logiciel>
</liste>
*/

foreach($logiciels as $logiciel){
  $noms = $logiciel->getElementsByTagName('nom');
  $nom = $noms->item(0)->firstChild;
  $commentaires = $logiciel->getElementsByTagName('commentaire');
  $commentaire = $commentaires->item(0)->firstChild;
  $pos = strpos($commentaire->nodeValue, ':');
  //Suppression du nom du logiciel
  $commentaire->deleteData(0, $pos + 1);
  $pos = strpos($commentaire->nodeValue, '(');
  $taille = strlen($commentaire->nodeValue);
  //Remplacement du prix entre parenthèses par un point terminal
  $commentaire->replaceData($pos, $taille - $pos, '.');
}

echo $doc_xml->saveXML();
//Retour à la source d'origine

Les méthodes appendData(), deleteData(), insertData(), replaceData() et substringData() s'appliquent à tous les noeuds héritant de la classe DOMCharacterData, en l'occurrence DOMText, DOMComment et DOMCDataSection.