TP : Java & XML

L'API JAXP/DOM (Document Object Model)

Écrire une petite application DOM permettant d'imprimer sur la sortie standard la liste des noms des unités d'enseignement (lecture du document et parcours de l'arbre). Vous pouvez utiliser la JavaDoc du package org.w3c.dom pour vous aider ainsi que l'exemple présenté en cours.

Note : depuis la version 1.4 de Java, les API SAX, DOM, JAXP et TrAX sont intégrées.

L'API TrAX (Transformation API for XML)

Construire un arbre DOM

Reprenez l'exercice précédent, et construisez un document DOM qui contient le résultat. Imprimez ce document (sous sa forme XML) en utilisant l'API TraX (Transformation API for XML). Pour ce faire, créer un Transformer avec l'aide d'un TransformerFactory. Vous devrez utiliser les packages suivants :

Pour vous aider, voila un petit exemple de création d'un arbre DOM :

package fr.univmed.massat.xml;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class SampleCreateDom {

   public static void main(String[] args) throws Exception {
      // création d'un document vide
      Document doc = DocumentBuilderFactory.newInstance()
            .newDocumentBuilder().newDocument();

      // ajout de noeuds
      Element racine = doc.createElement("racine");
      racine.appendChild(doc.createTextNode("hello"));
      doc.appendChild(racine);

      // sérialisation
      TransformerFactory myFactory = TransformerFactory.newInstance();
      Transformer transformer = myFactory.newTransformer();

      transformer.setOutputProperty(OutputKeys.ENCODING, "iso-8859-1");
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");

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

}

Appliquer une feuille de style XSL

Reprenez l'exercice précédent, et construisez une feuille de style (simple) pour produire du XHTML à partir du document XML résultat. Faites en sorte de lire cette feuille de style sous la forme d'un document DOM (DOMSource) et appliquez cette feuille de style (c'est une nouvelle transformation) sur le document XML résultat. Votre application doit maintenant imprimer la liste des noms d'unités sous la forme d'une page XHTML (en ISO-8859 indentée).

Important : à la fin de la séance envoyez vos codes Java et votre fichier XML en utlisant la commande ci-dessous :

/home/massat/public/envoyer-tps-xml noms-des-fichiers-a-envoyer

Utiliser Java API for XML Binding (JAXB)

Nous allons utiliser JAXB le framework de Binding Java/XML (qui est inclus dans java 1.6+).

  1. Testez l'utilisation du compilateur JAXB (l'application qui génère automatiquement les classes java à partir d'une DTD ou d'un schéma) :
    xjc -help
    
  2. Générez les classes java qui correspondent à votre DTD :
    mkdir -p src
    xjc -dtd -p monpkg -d src nom-de-votre-DTD
    
    Par curiosité, parcourez les fichiers Java générés.
  3. Préparer le code principal de votre application (fichier EssaiJAXB.java dans le répertoire src) :
    import java.io.File;
    
    public class EssaiJAXB {
    
        public static void main(String[] args) throws Exception {
            for (int i = 0; i < args.length; i++) {
                test(args[i]);
            }
        }
    
        private static void test(String fileName) throws Exception {
    
            JAXBContext context = JAXBContext.newInstance("monpkg");
    
            // creer les instances a partir du fichier XML
            Unmarshaller u = context.createUnmarshaller();
            Object o = u.unmarshal(new File(fileName));
    
            // serialiser les instances dans un document XML
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            m.marshal(o, System.out);
        }
    
    }
    
  4. Compilation de ces classes :
    mkdir -p classes
    javac -d classes -sourcepath src/ src/EssaiJAXB.java src/monpkg/*.java
    
  5. Exécution de votre application :
    java EssaiJAXB votre-fichier-xml
    
  6. Vous pouvez maintenant modifier votre application pour qu'elle ajoute une nouvelle unité avant de la sérialiser.
  7. Le compilateur JAXB fonctionne mieux avec un schéma à la place de la DTD. Pour obtenir de manière automatique un schéma à partir de votre DTD, suivez les indications de ce tutoriel.
  8. Vous pouvez maintenant utiliser xjc pour régénérer vos classes et testez le résultat. Quelles sont les différences par rapport à la version précédente ?
  9. Vous trouverez plus d'explications et d'exemples dans The Java Web Services Tutorial (notamment les chapitres 2 et 3) ou dans le cours en ligne de J.M. Doudoux.

L'API SAX (Simple API for XML)

A faire si il vous reste quelques forces...

Écrire une petite application SAX permettant d'extraire une information particulière d'un fichier XML. Par Exemple, le nom des unités d'enseignement. Vous pouvez utiliser la JavaDoc du package org.xml.sax pour vous aider.

Pour traiter cette question, vous aurez besoin d'un analyseur compatible SAX. Vous pouvez en télécharger un, mais il est plus simple d'utiliser celui intégré dans la JRE (Xerces). Pour ce faire, vous pouvez donner son nom en toute lettre dans le code

XMLReader xr = new com.sun.org.apache.xerces.internal.parsers.SAXParser();

mais dans ce cas, il existe un lien entre votre application et la version de la JRE (en l'occurrence la 5.0). Une solution préférable consiste à passer par l'interface JAXP pour se procurer l'analyseur SAX par défaut de la JRE sans savoir qu'il s'agit de Xerces :

// version JAXP
XMLReader xr = javax.xml.parsers.SAXParserFactory.
    newInstance().
        newSAXParser().
            getXMLReader();