Christophe Jacquet, Associate Professor at Supélec

Enseignement > Exemples en Java >

Manipulation de fichiers XML grâce à l'API DOM

L'API DOM permet de manipuler facilement des fichiers XML en tirant parti de leur structure d'arbre. Cet exemple couvre les points suivants :

Cet exemple se base uniquement sur les API standard de Java (version 5). Il est également possible d'utiliser d'autres implémentations de DOM, comme Xerces.

/* ############################################################################
 * 
 * XMLDOM.java : création, écriture, lecture et parcours d'arbres XML en
 *               utilisant l'API DOM.
 * 
 * Auteur : Christophe Jacquet, Supélec
 * 
 * Historique
 * 2006-11-27  Création
 * 
 * ############################################################################
 */

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

public class XMLDOM {
	/**
	 * Crée un petit document XML d'exemple, à l'aide d'un Document Builder.
	 * 
	 * @param docBuilder un document builder
	 * @return un document XML d'exemple, sous forme d'un objet DOM Document
	 */
	private static Document creerDocumentExemple(DocumentBuilder docBuilder) {
		Document doc = docBuilder.newDocument();
		
		Element racine = doc.createElement("root");
		racine.setAttribute("lang", "fr");
		doc.appendChild(racine);
		
		Element sujet = doc.createElement("node");
		sujet.setAttribute("role", "sujet");
		sujet.setTextContent("Supélec");
		racine.appendChild(sujet);
		
		Element verbe = doc.createElement("node");
		verbe.setAttribute("role", "verbe");
		verbe.setTextContent("est");
		racine.appendChild(verbe);
		
		Element complement = doc.createElement("node");
		complement.setAttribute("role", "complément de lieu");
		complement.setTextContent("en France");
		racine.appendChild(complement);
		
		return doc;
	}
	
	/**
	 * Écrit dans un fichier un document DOM, étant donné un nom de fichier.
	 * 
	 * @param doc le document à écrire
	 * @param nomFichier le nom du fichier de sortie
	 */
	private static void ecrireDocument(Document doc, String nomFichier) {
		// on considère le document "doc" comme étant la source d'une 
		// transformation XML
		Source source = new DOMSource(doc);
		
		// le résultat de cette transformation sera un flux d'écriture dans
		// un fichier
		Result resultat = new StreamResult(new File(nomFichier));
		
		// création du transformateur XML
		Transformer transfo = null;
		try {
			transfo = TransformerFactory.newInstance().newTransformer();
		} catch(TransformerConfigurationException e) {
			System.err.println("Impossible de créer un transformateur XML.");
			System.exit(1);
		}
		
		// configuration du transformateur
		
		// sortie en XML
		transfo.setOutputProperty(OutputKeys.METHOD, "xml");
		
		// inclut une déclaration XML (recommandé)
		transfo.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
		
		// codage des caractères : UTF-8. Ce pourrait être également ISO-8859-1
		transfo.setOutputProperty(OutputKeys.ENCODING, "utf-8");
		
		// idente le fichier XML
		transfo.setOutputProperty(OutputKeys.INDENT, "yes");
		
		try {
			transfo.transform(source, resultat);
		} catch(TransformerException e) {
			System.err.println("La transformation a échoué : " + e);
			System.exit(1);
		}
	}
	
	/**
	 * Lit un document XML à partir d'un fichier sur le disque, et construit
	 * le document DOM correspondant.
	 * 
	 * @param docBuilder une instance de DocumentBuilder
	 * @param nomFichier le fichier où est stocké le document XML
	 * @return un objet DOM Document correspondant au document XML 
	 */
	private static Document lireDocument(DocumentBuilder docBuilder, 
			String nomFichier) {
		
		try {
			return docBuilder.parse(new File(nomFichier));
		} catch(SAXException e) {
			System.err.println("Erreur de parsing de " + nomFichier);
		} catch (IOException e) {
			System.err.println("Erreur d'entrée/sortie sur " + nomFichier);
		}
		
		return null;
	}
	
	/**
	 * Affiche à l'écran un document XML fourni sous forme d'un objet DOM
	 * Document.
	 * 
	 * @param doc le document
	 */
	private static void afficherDocument(Document doc) {
		Element e = doc.getDocumentElement();
		afficherElement(e);
	}
	
	/**
	 * Affiche à l'écran un élément XML, ainsi que ses attributs, ses noeuds
	 * de texte, et ses sous-éléments.
	 * 
	 * @param e l'élément à afficher
	 */
	private static void afficherElement(Element e) {
		System.out.print("<" + e.getNodeName() + " ");
		
		NamedNodeMap attr = e.getAttributes();
		for(int i=0; i<attr.getLength(); i++) {
			Attr a = (Attr)attr.item(i);
			System.out.print(a.getName() + "=\"" + a.getNodeValue() + "\" ");
		}
		System.out.println(">");
		
		for(Node n = e.getFirstChild(); n != null; n = n.getNextSibling()) {
			switch(n.getNodeType()) {
			case Node.ELEMENT_NODE:
				afficherElement((Element)n);
				break;
			case Node.TEXT_NODE:
				String data = ((Text)n).getData();
				System.out.print(data);
				break;
			}
		}
		System.out.println("</" + e.getNodeName() + ">");
	}
	
	public static void main(String[] args) {
		// obtention d'un Document Builder qui permet de créer de nouveaux
		// documents ou de parser des documents à partir de fichiers
		DocumentBuilder docBuilder = null;

		try {
			docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		} catch(ParserConfigurationException e) {
			System.err.println("Impossible de créer un DocumentBuilder.");
			System.exit(1);
		}
		
		// crée un petit document d'exemple
		Document doc = creerDocumentExemple(docBuilder);
		
		// l'écrire sur le disque dans un fichier
		ecrireDocument(doc, "test.xml");
		
		// re-charger ce document à partir du fichier
		Document doc2 = lireDocument(docBuilder, "test.xml");
		if(doc2 == null) System.exit(1);

		afficherDocument(doc2);
	}
}