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 par l'invocation des méthodes de création de l'objet Document.

Attr attribut = document.createAttribute("unAttribut");
Attr attr_ns = document.createAttributeNS(
                         "http://www.laltruiste.com/", "lal:unAttribut");
CDATASection cdata = 
             document.createCDATASection("Un texte non analysable...");
Comment commentaire = document.createComment("Un commentaire...");
Element element = document.createElement("unElement", "Une valeur...");
Element elt_ns = document.createElementNS(
                         "http://www.laltruiste.com/", "lal:unElement", "Une valeur...");
EntityReference entite = document.createEntityReference("&");
ProcessingInstruction pi = document.createProcessingInstruction(
                         "xml-stylesheet", "href="style.xsl" type="text/xsl"");
Text texte = document.createTextNode("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 Node.

DocumentBuilderFactory fabriqueDOM = DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabriqueDOM.newDocumentBuilder();
Document document = analyseur.newDocument();
document.setXmlVersion("1.0");
document.setXmlEncoding("ISO-8859-1");
Element racine = document.createElement("racine");
document.appendChild(racine);

/*création de :
<?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.

Element enfant = document.createElement("enfant");
racine.appenChild(enfant);
CDATASection cdata = document.createCDATASection("<balise/> -> Balise vide");
Node noeud_ajoute = enfant.appendChild(cdata);

/*création de :
<?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.

  • 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.
  • 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.
  • 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.
  • NOT_SUPPORTED_ERR est lancée si le nouveau noeud est un enfant du noeud Document.

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 Element.

Element element = document.createElement("elt");
boolean reussi = element.setAttribute("attribut", "valeur");
Attr attribut = document.createAttribute("attribut", "valeur");
reussi = element.setAttributeNode(attribut);
attr_ns = element.setAttributeNS(
                        "http://www.laltruiste.com/", 
                        "lal:attr_ns", 
                        "Valeur de l'attribut");

Attr attribut_ns = document.createAttribute("lal:attribut_ns");
attribut_ns.setValue("Une valeur d'attribut");
Attr nouv_attr = element.setAttributeNodeNS(attribut_ns);
if(attribut_ns.isSameNode(attribut_ns))
  System.out.println("Le noeud a bien été ajouté puisqu'ils sont identiques !");

/*création de :
<?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 méthode setValue() ou setNodeValue() héritée de l'objet Node.

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

Node clone = enfant.clonNode(true);
racine.appendChild(clone);

/*création de :
<?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 avait 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é.

Document nouv_doc = analyseur.newDocument();
nouv_doc.setXmlVersion("1.0");
nouv_doc.setXmlEncoding("ISO-8859-1");
Node import = nouv_doc.importNode(enfant, true);
nouv_doc.appendChild(import);

/*création de :
<?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>
*/

La méthode adoptNode() déplace un noeud et son arborescence d'un document vers un autre. Le noeud cible de l'adoption est supprimé de son document d'appartenance et est placé dans le document hôte. Contrairement à la méthode importNode(), le noeud n'existe plus dans le document d'origine après l'adoption de ce dernier.

Node adopte = document.adoptNode(enfant);

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

Document document = analyseur.newDocument();
document.setXmlVersion("1.0");
document.setXmlEncoding("ISO-8859-1");
Element element = document.createElement("zoneTexte");
EntityReference ref = document.createEntityReference("eacute");
Text texte1 = document.createtextNode("La r");
Text texte2 = document.createtextNode("f");
Text texte3 = document.createtextNode("rence d'entit");
elt.appendChild(texte1);
element.appendChild(ref);
element.appendChild(texte2);
element.appendChild(ref.cloneNode());
element.appendChild(texte3);
element.appendChild(ref.cloneNode());
document.appendChild(element);

/*création de :
<?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 CharacterData.

Document document = analyseur.newDocument();
document.setXmlVersion("1.0");
document.setXmlEncoding("ISO-8859-1");
Element element = document.createElement("citation");
CDATASection texte = document.createCDATASection("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);
document.appendChild(element);

/*création de :
<?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>
*/