La création ou la modification d'un document XML existant s'accomplit aisément avec les outils proposés par le DOM.

La création d'objets du DOM s'obtient soit par l'instanciation des objets, soit par les méthodes de création de l'objet DOMDocument.

$attribut = $doc_xml->createAttribute('unAttribut');
$attr_ns = $doc_xml->createAttributeNS(
                         'http://www.laltruiste.com/', 'lal:unAttribut');
$cdata =  $doc_xml->createCDATASection('Un texte non analysable...');
$commentaire = $doc_xml->createComment('Un commentaire...');
$element = $doc_xml->createElement('unElement', 'Une valeur...');
$elt_ns = $doc_xml->createElementNS(
                         'http://www.laltruiste.com/', 'lal:unElement', 'Une valeur...');
$entite = $doc_xml->createEntityReference('&');
$pi = $doc_xml->createProcessingInstruction(
                         'xml-stylesheet', 'href="style.xsl" type="text/xsl"');
$texte = $doc_xml->createTextNode('Un texte...');

$attribut = new DOMAttr('unAttribut', 'Une valeur');
$attr_ns = new DOMAttr('unAttribut', 'Une valeur');
$attr_ns->namespaceURI = 'http://www.laltruiste.com/';
$attr_ns->prefix = 'lal';
$cdata =  new DOMCDATASection('Un texte non analysable...');
$commentaire = new DOMComment('Un commentaire...');
$element = new DOMElement('unElement', 'Une valeur...');
$elt_ns = new DOMElement(
                 'lal:unElement', 
                 'Une valeur...', 
                 'http://www.laltruiste.com/');
$entite = new DOMEntity('&á');
$pi = new DOMProcessingInstruction(
                         'xml-stylesheet', 'href="style.xsl" type="text/xsl"');
$texte = new DOMText('Un texte...');

Désormais, il faut pouvoir insérer ces objets au sein d'un document XML.

Les noeuds éléments ou textuels se greffent dans un document par l'intermédiaire de la méthode appendChild() de l'objet DOMNode.

$doc_xml = new DOMDocument('1.0', 'ISO-8859-1');
$racine = new DOMElement('racine');
$doc_xml->appendChild($racine);
echo $doc_xml->saveXML();
/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine/>
*/

L'ajout d'un élément ou d'un texte à un élément parent est identique. Le noeud cible de l'ajout doit invoquer la méthode appendChild() pour qu'un nouveau noeud soit ajouter en son sein et à la fin de ses enfants éventuels.

$enfant = new DOMElement('enfant');
$racine->appenChild($enfant);
$cdata = new DOMCDATASection('<balise/> -> Balise vide');
$noeud_ajoute = $enfant->appendChild($cdata);
echo $doc_xml->saveXML();

/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine>
<enfant>
<![CDATA[<balise/> -> Balise vide]]>
</enfant>
</racine>
*/

La méthode appendChild() retourne le noeud nouvellement ajouté. En outre, cette méthode est susceptible de lancer des exceptions.

  • DOM_NO_MODIFICATION_ALLOWED_ERR est lancée si le noeud est en lecture seul ou si le parent précédent le noeud à ajouter est en lecture seul.
  • DOM_HIERARCHY_REQUEST_ERRest lancée si le noeud est d'un type qui n'autorise pas d'enfant du type du nouveau noeud, ou si le noeud à ajouter est un des noeuds ancêtres ou ce noeud lui-même.
  • DOM_WRONG_DOCUMENT_ERR est lancée si le nouveau noeud a été créé à partir d'un document différent que celui qui a créé ce noeud.

Les attributs s'ajoutent aux éléments d'une manière différente. En effet, il faut passer par les méthodes d'ajout d'attribut de l'objet DOMElement.

$element = new DOMElement('elt');
$reussi = $element->setAttribute('attribut', 'valeur');
$attribut = new DOMAttr('attribut', 'valeur');
$reussi = $element->setAttributeNode($attribut);
$attr_ns = $element->setAttributeNS(
                        'http://www.laltruiste.com/', 
                        'lal:attr_ns', 
                        'Valeur de l\'attribut');

$attribut_ns = new DOMAttr('lal:attribut_ns');
$attribut_ns->nodeValue = 'Une valeur d\'attribut';
$nouv_attr = $element->setAttributeNodeNS($attribut_ns);
if($attribut_ns->isSameNode($attribut_ns))
  echo 'Le noeud a bien été ajouté puisqu\'il sont identiques !';
echo $doc_xml->saveXML();

/*Affiche :
Le noeud a bien été ajouté puisqu'il sont identiques !
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine>
  <enfant>
    <![CDATA[<balise/> -> Balise vide]]>
    <elt 
            xmlns:lal="http://www.laltruiste.com/" 
            attribut="valeur" 
            lal:attr_ns="Valeur de l'attribut" 
            lal:attribut_ns="Une valeur d'attribut"/>
  </enfant>
</racine>
*/

L'ajout ou la modification d'une valeur textuelle à un attribut s'effectue par l'intermédiaire de la propriété nodeValue.

Le clonage des noeuds se réalise avec la méthode cloneNode() de l'objet DOMNode.

$clone = $enfant->clonNode(true);
$racine->appendChild($clone);
echo $doc_xml->saveXML();

/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine>
  <enfant>
    <![CDATA[<balise/> -> Balise vide]]>
    <elt 
            xmlns:lal="http://www.laltruiste.com/" 
            attribut="valeur" 
            lal:attr_ns="Valeur de l'attribut" 
            lal:attribut_ns="Une valeur d'attribut"/>
  </enfant>
  <enfant>
    <![CDATA[<balise/> -> Balise vide]]>
    <elt 
            xmlns:lal="http://www.laltruiste.com/" 
            attribut="valeur" 
            lal:attr_ns="Valeur de l'attribut" 
            lal:attribut_ns="Une valeur d'attribut"/>
  </enfant>
</racine>
*/

Si ce genre d'ajout avait été tenté sans clonage :

  • soit la commande aurait été inopérante puisque le noeud a déjà été ajouté,
  • soit, dans le cas d'une insertion dans un autre noeud que le parent du noeud courant, une exception Hierarchy Request Error aurait été levée puisque le noeud était déjà utilisé ailleurs.

La méthode importNode() de l'objet DOMDocument fournit un moyen d'importation d'un noeud avec éventuellement toute sa descendance au sein d'un autre document que le propriétaire du noeud importé.

$nouv_doc = new DOMDocument('1.0', 'ISO-8859-1');
$import = $nouv_doc->importNode($enfant, true);
$nouv_doc->appendChild($import);
echo $nouv_doc->saveXML();

/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<enfant>
  <![CDATA[<balise/> -> Balise vide]]>
  <elt 
          xmlns:lal="http://www.laltruiste.com/" 
          attribut="valeur" 
          lal:attr_ns="Valeur de l'attribut" 
          lal:attribut_ns="Une valeur d'attribut"/>
</enfant>
*/

Les références d'entité peuvent être ajoutées directement dans un élément avec la méthode appendChild().

$doc_xml = new DOMDocument('1.0', 'ISO-8859-1');
$element = $doc_xml->createElement('zoneTexte');
$ref = $doc_xml->createEntityReference('eacute');
$texte1 = $doc_xml->createtextNode('La r');
$texte2 = $doc_xml->createtextNode('f');
$texte3 = $doc_xml->createtextNode('rence d\'entit');
$elt->appendChild($texte1);
$element->appendChild($ref);
$element->appendChild($texte2);
$element->appendChild($ref->cloneNode());
$element->appendChild($texte3);
$element->appendChild($ref->cloneNode());
$doc_xml->appendChild($element);
echo $doc_xml->saveXML();

/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<zoneTexte>
  La référence d'entité
</zoneTexte>
*/

Les chaînes de caractères peuvent être ajoutées ou insérées dans un objet textuel à l'aide des méthodes appendData() et insertData(), voire même replaceData() de l'objet DOMCharacterData.

$doc_xml = new DOMDocument('1.0', 'ISO-8859-1');
$element = $doc_xml->createElement('citation');
$texte = new DOMCDATASection('On n\'est jamais si hereu');
$texte->appendData('ni si malheureux qu\'on s\'imagine.');
$texte->appendData('La Rochefoucauld, Maximes.');
$texte->replaceData(19, 5, 'heureux');
$texte->insertData(26, ' ');
$texte->insertData(60, '<br/>(');
$texte->insertData(0, '<p>');
$texte->appendData(')</p>');
$element->appendChild($texte);
$doc_xml->appendChild($element);
echo $doc_xml->saveXML();

/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<citation>
  <![CDATA[
     <p>On n'est jamais si heureux ni 
            si malheureux qu'on s'imagine.
            </br>(La Rochefoucauld, Maximes.)</p>]]>
</citation>
*/