FRFAM.COM >> Famille >> Technologie &Innovation >> Informatique

Lire et écrire des fichiers XML en Java avec l'API DOM : Tutoriel complet

Apprenez à lire et écrire des fichiers XML en Java de manière simple et efficace avec l'API DOM.

Les fichiers XML sont polyvalents pour le stockage et l'échange de données structurées. Avant l'essor de JSON, XML dominait ce domaine. Sa popularité a baissé, mais il reste essentiel dans de nombreux systèmes legacy. Maîtriser son traitement en Java est un atout précieux pour tout développeur.

La Java SE intègre l'API JAXP (Java API for XML Processing), couvrant tous les aspects du XML :

  • DOM : Modèle objet en mémoire pour manipuler éléments, nœuds et attributs. Idéal pour petits fichiers, inadapté aux gros volumes.
  • SAX : Analyse événementielle à faible mémoire, mais complexe à coder.
  • StAX : Streaming performant en mode "pull", plus simple que SAX.

Ce tutoriel se concentre sur l'API DOM pour lire et écrire des XML. SAX et StAX seront abordés ultérieurement.

Exemple de fichier XML

Utilisons ce fichier XML d'exemple :

<?xml version="1.0"?>
<catalog>
  <book id="bk101">
    <author>Gambardella, Matthieu</author>
    <title>Guide du développeur XML</title>
    <genre>Ordinateur</genre>
    <price>44,95</price>
    <publish_date>2000-10-01</publish_date>
    <description>Un regard approfondi sur la création d'applications avec XML.</description>
  </book>
  <book id="bk102">
    <author>Ralls, Kim</author>
    ...
  </book>
</catalog>

Lire un fichier XML

Étapes basiques avec DOM :

Créez un DocumentBuilder :

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
DocumentBuilder builder = factory.newDocumentBuilder();

Chargez le document :

File file = ...; // Fichier XML
Document document = builder.parse(file);
Element catalog = document.getDocumentElement();

L'API DOM simplifie grandement la lecture. Vous accédez maintenant à tout le document via sa racine.

Utiliser l'API DOM

Extrayez les données de la racine catalog :

Parcourez les enfants book :

NodeList books = catalog.getChildNodes();
for (int i = 0, ii = 0, n = books.getLength(); i < n; i++) {
    Node child = books.item(i);
    if (child.getNodeType() != Node.ELEMENT_NODE) continue;
    Element book = (Element) child;
    // Traiter book
}

Fonction utilitaire pour trouver un élément enfant :

private static Node findChildElement(Node parent, String tagName) {
    NodeList children = parent.getChildNodes();
    for (int i = 0, len = children.getLength(); i < len; i++) {
        Node child = children.item(i);
        if (child.getNodeType() == Node.ELEMENT_NODE &&
            tagName.equals(child.getNodeName())) {
            return child;
        }
    }
    return null;
}

Récupérer le texte d'un élément (gère les TEXT_NODE multiples) :

private static String getCharacterData(Node parent) {
    StringBuilder text = new StringBuilder();
    NodeList children = parent.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        Node child = children.item(i);
        if (child.getNodeType() == Node.TEXT_NODE) {
            text.append(child.getNodeValue().trim());
        }
    }
    return text.toString();
}

Exemple complet pour lister les livres :

NodeList books = catalog.getChildNodes();
for (int i = 0, ii = 0, n = books.getLength(); i < n; i++) {
    Node child = books.item(i);
    if (child.getNodeType() != Node.ELEMENT_NODE) continue;
    Element book = (Element) child;
    ii++;
    String id = book.getAttribute("id");
    String author = getCharacterData(findChildElement(book, "author"));
    String title = getCharacterData(findChildElement(book, "title"));
    String genre = getCharacterData(findChildElement(book, "genre"));
    String price = getCharacterData(findChildElement(book, "price"));
    String publishDate = getCharacterData(findChildElement(book, "publish_date"));
    String description = getCharacterData(findChildElement(book, "description"));
    System.out.printf("%3d. ID du livre = %s\n" +
                      "Auteur: %s\n" +
                      "Titre: %s\n" +
                      "Genre: %s\n" +
                      "Prix: %s\n" +
                      "Date publication: %s\n" +
                      "Description: %s\n",
                      ii, id, author, title, genre, price, publishDate, description);
}

Écrire un fichier XML

L'API de Transformation XML permet d'écrire via une transformation d'identité.

Ajoutons un nouveau book via un fichier properties :

id=bk113
author=Jane Austen
title=Orgueil et préjugés
genre=Romance
price=6.99
publish_date=2010-04-01
description="C'est une vérité universellement reconnue qu'un célibataire en possession d'une bonne fortune doit avoir besoin d'une femme." Ainsi commence Orgueil et Préjugés...

Chargez l'XML existant :

File file = ...;
Document document = builder.parse(file);
Element catalog = document.getDocumentElement();

Chargez les properties :

String propsFile = ...;
Properties props = new Properties();
try (FileReader in = new FileReader(propsFile)) {
    props.load(in);
}

Récupérez les valeurs :

String id = props.getProperty("id");
String author = props.getProperty("author");
String title = props.getProperty("title");
String genre = props.getProperty("genre");
String price = props.getProperty("price");
String publishDate = props.getProperty("publish_date");
String description = props.getProperty("description");

Créez le book :

Element book = document.createElement("book");
book.setAttribute("id", id);

Ajoutez les enfants :

List<String> elNames = Arrays.asList("author", "title", "genre", "price", "publish_date", "description");
for (String elName : elNames) {
    Element el = document.createElement(elName);
    Text text = document.createTextNode(props.getProperty(elName));
    el.appendChild(text);
    book.appendChild(el);
}
catalog.appendChild(book);

Configurez le transformer avec indentation :

TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", "3");

Transformez :

transformer.transform(new DOMSource(document), new StreamResult(System.out));

Ou dans un fichier :

transformer.transform(new DOMSource(document), new StreamResult(new File("output.xml")));

Voilà pour la lecture et écriture XML avec DOM !

Avez-vous utilisé l'API DOM ? Partagez votre expérience en commentaires.

[]