Ce TP est une introduction à XML et XSL.
Il a pour objectif de vous montrer les grands principes et les principales API java de ces langages, sans pour autant trop rentrer dans les détails.
Si vous souhaitez en apprendre plus, la dernière section “Pour approfondir ce qui vient d'être présenté” vous propose une liste de liens vers d'autres tutoriels plus complets. archive des fichiers utilisés
XML est un format de représentation de données. C'est à dire qu'il offre une manière particulière de stocker des données.
XML utilise des représentations sous forme d'arbre: un arbre est composé d'une racine (le tronc), de branches et de feuilles.
Ce qu'XML représente, ce sont des noeuds: le premier noeud d'un document est la racine du document, les autres noeuds sont des branches ou des feuilles.
Regardez le document document1.xml de l'archive:
Un noeud peut également contenir des propriétés (attribute) qui sont spécifiés lors de la déclaration sous forme de pair-valeur:
<NomDuNoeud attribut1="valeur1" attribut2="valeur2"> contenu du noeud <!-- un commentaire --> <UnAutreNoeud/> </NomDuNoeud>
Un format XML peut être décrit dans une DTD ou un schema XML: ces documents expliquent comment un document doit être organisé.
Regardez par exemple la DTD et le schema proposé dans l'archive: que décrivent-ils?
Quel format XML connaissez-vous déjà ?
Inventez un petit format XML ?
Java offre plusieurs API permettant de manipuler des fichiers XML.
Nous vous en présentons deux par l'exemple, qui sont chacune représentatives des deux grandes techniques de parcours d'arbre XML: le parcours événementiel et le parcours global.
L'API SAX de java permet d'accéder aux document XML de manière événementielle.
Prenez en main le code suivant:
package sax; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.helpers.DefaultHandler; /** * Handler trivial pour SAX * Ce handler se contente d'afficher les balises ouvrantes et fermantes. * @author O. Carton * @version 1.0 */ public class TrivialSAXHandler extends DefaultHandler { public void setDocumentLocator(Locator locator) { System.out.println("Location : " + "publicId=" + locator.getPublicId() + " systemId=" + locator.getSystemId()); } public void startDocument() { System.out.println("Debut du document"); } public void endDocument() { System.out.println("Fin du document"); } public void startElement(String namespace, String localname, String qualname, Attributes atts) { System.out.println("Balise ouvrante : " + "namespace=" + namespace + " localname=" + localname + " qualname=" + qualname); } public void endElement(String namespace, String localname, String qualname) { System.out.println("Balise fermante : " + "namespace=" + namespace + " localname=" + localname + " qualname=" + qualname); } public void characters(char[] ch, int start, int length) { System.out.print("Caractères : "); for(int i = start; i < start+length; i++) System.out.print(ch[i]); System.out.println(); } }
et la classe principale:
package sax; // IO import java.io.InputStream; import java.io.FileInputStream; // SAX import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; /** * Lecture triviale d'un document XML avec SAX * @author O. Carton * @version 1.0 */ public class TrivialSAXRead { public static void main(String [] args) throws Exception { // Création de la fabrique de parsers SAXParserFactory parserFactory = SAXParserFactory.newInstance(); // Création du parser SAXParser parser = parserFactory.newSAXParser(); // Lecture de chaque fichier passé en paramètre for(int i = 0; i < args.length; i++) { // Flux d'entrée InputStream is = new FileInputStream(args[i]); parser.parse(is, new TrivialSAXHandler()); } } }
L'API DOM de java permet de charger complètement et d'un seul coup un document XML en mémoire
Prenez en main le code suivant:
package dom; //IO import java.io.InputStream; import java.io.FileInputStream; //DOM import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; /** * Lecture triviale d'un document XML avec DOM * @author O. Carton * @version 1.0 */ public class TrivialDOMRead { public static void main(String [] args) throws Exception { // Création de la fabrique de constructeur de documents DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // Création du constructeur de documents DocumentBuilder documentBuilder = dbf.newDocumentBuilder(); // Lecture de chaque fichier passé en paramètre for(int i = 0; i < args.length; i++) { // Flux d'entrée InputStream is = new FileInputStream(args[i]); // Construction du document Document doc = documentBuilder.parse(is); // Exploitation du document ... System.out.println(doc); } } }
SAX et DOM offrent de nombreuses méthodes pour créer des document XML, les exploiter, les modifier, les sauvegarder, etc.
Reagrdez le code suivant:
try { // Création d'un nouveau DOM DocumentBuilderFactory fabrique =DocumentBuilderFactory.newInstance(); DocumentBuilder constructeur = fabrique.newDocumentBuilder(); Document document = constructeur.newDocument(); // Propriétés du DOM document.setXmlVersion("1.0"); document.setXmlStandalone(true); //Création de l'arborescence du DOM /racine Element racine = document.createElement("nomRacine"); racine.setAttribute("version", "v1.4"); Element fils = document.createElement("nomFils"); // ajout du fils à la racine racine.appendChild(obs); //ajout de la racine au document document.appendChild(racine); /* Sauvegarde du fichier xml */ Source source = new DOMSource(document); // Création du fichier de sortie File f = new File("fichier.xml"); Result resultat = new StreamResult(f); // Configuration du transformer TransformerFactory tfabrique = TransformerFactory.newInstance(); Transformer transformer = tfabrique.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // Transformation transformer.transform(source, resultat); } catch (ParserConfigurationException pce) {pce.printStackTrace();} catch (TransformerConfigurationException tce) {tce.printStackTrace();} catch (TransformerException te) {te.printStackTrace();}
XSL est un langage XML de transformation de document XML.
XSL utilise une approche événementielle pour le traitement des document XML.
Regardez le fichier transfo1.xsl. Que fait ce fichier? Comment utiliser ce fichier sur un document XML?
Java permet l'appel de feuille xsl de transformation dans ses différentes API.
Regardez le code suivant:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //configuration de la fabrique factory.setNamespaceAware(true); factory.setValidating(true); factory.setIgnoringElementContentWhitespace(true); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(false); try { //sinon, génère parfois des null pointer exp au parsage (problème avecsimples quote) factory.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new File(entree)); doc.setStrictErrorChecking(true); TransformerFactory transformFactory = new TransformerFactoryImpl(); StreamSource styleSource = new StreamSource(new File(ADRESSE_XSL)); // lire le style Transformer transform = transformFactory.newTransformer(styleSource); //Si besoin : transform.setOutputProperty(name, value) DOMSource in = new DOMSource(doc); // Création du fichier de sortie File file = new File(cible); Result resultat = new StreamResult(fichier); //Si besoin : transform.setParameter("nomDuParam",valeur); transform.transform(in, out); }
Regardez la documentation de la fonction count de XSL.
Quelle technique vous semble la plus facile à utiliser?