Développement Java - XML Développement Java - XML Jean-Michel Richer [email protected] http://www.info.univ-angers.fr/pub/richer M1/M2 Informatique 2010-2011 1 / 48 Développement Java - XML Plan Plan 1 Introduction 2 DOM 3 SAX 4 XPath 5 Application 6 Bibliographie 2 / 48 Développement Java - XML Plan XML avec Java Objectifs • se familiariser avec le traitement des fichiers XML en Java • utilisation avec DOM • utilisation avec SAX • utilisation de XPath 3 / 48 Développement Java - XML Introduction Introduction Introduction 4 / 48 Développement Java - XML Introduction Rappel XML XML (eXtensible Markup Language) • standard W3C pour représentation des données dans des documents balisés • définition structurée de l’information (syntaxe + sémantique) • représentation arborescente • possibilité de définir une grammaire (Document Type Definition) : validation 5 / 48 Développement Java - XML Introduction JAXP JAXP (Java API for XML Processing) capacité à lire et valider les documents XML, formée de trois composants : • DOM (Document Object Model) : tree-based • SAX (Simple API for XML) : event-based • StAX (Streaming API for XML) (entre DOM et SAX) http://jaxp.java.net 6 / 48 Développement Java - XML Introduction StAX StAX (Streaming API for XML) entre DOM et SAX • peu gourmand en mémoire • accès séquentiel aux données : mais contrairement à SAX on indique quel est le prochain élément à traiter • écriture de fichiers XML • StAX ne sera pas traité dans ce document 7 / 48 Développement Java - XML DOM DOM DOM 8 / 48 Développement Java - XML DOM DOM DOM (Document Object Model) • API permettant d’accéder au contenu d’un document XML sous la forme d’une structure arborescente • chargement complet du document XML • réservé à de petits fichiers et lecture linéaire 9 / 48 Développement Java - XML DOM DOM et Java DOM et Java • se référer au package org.w3c.dom • le parser est issu de javax.xml.parsers.DocumentBuilder • obtenu depuis javax.xml.parsers.DocumentBuilderFactory 10 / 48 Développement Java - XML DOM Fichier exemple Exemple de travail 1 <?xml version="1.0" encoding="UTF-8"?> 2 <persons> 3 <person id="1"> 4 <first-name>Donald</first-name> 5 <last-name>Duck</last-name> 6 <date-of-birth>01-01-1970</date-of-birth> 7 <salary>1000.0</salary> 8 </person> 9 <person id="2"> 10 <first-name>Picsou</first-name> 11 <last-name>Duck</last-name> 12 <date-of-birth>02-01-1960</date-of-birth> 13 <salary>120000.0</salary> 14 </person> 15 <person id="3"> 16 <first-name>Mickey</first-name> 17 <last-name>Mouse</last-name> 18 <date-of-birth>01-01-1980</date-of-birth> 19 <salary>3000.20</salary> 20 </person> 21 </persons> 11 / 48 Développement Java - XML DOM DOM création du parser Exemple 1 2 3 4 5 6 7 8 9 10 11 12 13 // ouverture d’un document XML sous DOM File fXmlFile = new File(fileName); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); // use DTD validation dbFactory.setValidating(true); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); // report Errors if DTD validation is On // note: ErrorHandler must be defined dBuilder.setErrorHandler(new ErrorHandler()); Document doc = dBuilder.parse(fXmlFile); doc.getDocumentElement().normalize(); 12 / 48 Développement Java - XML DOM DOM lecture <tag>value</tag> lecture <tag>value</tag> 1 2 3 4 5 6 7 8 9 10 11 12 13 NodeList nList; // Obtain all nodes for last name nList = doc.getElementsByTagName("last-name"); // treat each node for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT NODE) { nNode.getTextContent().trim()); } } 13 / 48 Développement Java - XML DOM DOM lecture <tag attr="value" /> lecture <tag attr="value" /> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 NodeList nList; // get all nodes person nList = doc.getElementsByTagName("person"); // treat each node for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT NODE) { Element eElement = (Element) nNode; // retrieve attribute id String id=eElement.getAttribute("id").trim(); // note : attribute nationality is not defined in persons.xml // so getAttribute will return an empty String String nationality=eElement.getAttribute("nationality").trim(); if (nationality.isEmpty()) { nationality="french"; } } } attribut inexistant : chaı̂ne vide ! 14 / 48 Développement Java - XML SAX SAX SAX 15 / 48 Développement Java - XML SAX SAX SAX (Simple API for XML) • API permettant d’accéder au contenu d’un document XML de manière événementielle (≃ yacc) • chargement partiel du document XML • réservé à de gros fichiers et lecture non linéaire 16 / 48 Développement Java - XML SAX SAX Handler SAX Handler • définir une classe SAXReader qui hérite de org.xml.sax.helpers.DefaultHandler • implanter les méthodes de l’interface ContentHandler 17 / 48 Développement Java - XML SAX méthodes de DefaultHandler méthodes de DefaultHandler ce sont celles de ContentHandler, pour les principales : • startDocument • startElement • characters • endElement • endDocument voir également les autres méthodes pour les documents XML plus complexes 18 / 48 Développement Java - XML SAX méthode characters méthode characters elle permet de lire une chaı̂ne de caractères à l’intérieur d’une balise : <tag>value</tag> ici, on récupérera : value 19 / 48 Développement Java - XML SAX méthode startElement méthode startElement elle permet de traiter les attributs : <tag attr="vattr">...</tag> en vérifiant quelle est la valeur de la balise tag 20 / 48 Développement Java - XML SAX méthode endElement méthode endElement elle permet de traiter : <tag>value</tag> en vérifiant quelle est la valeur de la balise tag 21 / 48 Développement Java - XML SAX méthodes start/endElement lecture <tag attr="vattr">value</tag> il faut combiner les deux méthodes • startElement : pour lire les attributs et créer une structure de données • puis endElement pour lire value et l’affecter à la structure de données 22 / 48 Développement Java - XML SAX SAX création parser Exemple 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; public class SAXReader extends DefaultHandler { protected String text; public SAXReader() throws Exception { super(); } public void read(String fileName) { try { XMLReader parser = XMLReaderFactory.createXMLReader(); parser.setContentHandler(this); parser.setFeature("http://xml.org/sax/features/validation", true); parser.parse(fileName); } catch (Exception e) { System.err.println(e.getMessage()); } } public void characters(char[] ch, int start, int length) throws SAXException { text = new String(ch, start, length); } 23 / 48 Développement Java - XML SAX SAX lecture lecture <tag>value</tag> 1 // read <tag>value</tag> 2 public void endElement(String uri, String localName, String qName) 3 throws SAXException { 4 if (localName.equals("tag")) { 5 6 String value = text.trim(); 7 8 9 } 10 } 11 24 / 48 Développement Java - XML SAX SAX lecture lecture <tag attr="value" /> 1 // read <tag attr=”vattr” /> 2 public void startElement(String uri, String localName, String qName, 3 Attributes atts) throws SAXException { 4 5 if (localName.equals("tag")) { 6 String vattr = atts.getValue("attr").trim(); 7 8 // note : be careful because atts.getValue will return null 9 10 // if attribute is not present 11 if (vattr==null) { 12 vattr=""; 13 } 14 } 15 16 } attribut inexistant : null ! 25 / 48 Développement Java - XML XPath XPath XPath 26 / 48 Développement Java - XML XPath XPath XPath (XML Path Language) • est à XML ce que SQL est aux SGBD-R • langage de sélection de balises / attributs 27 / 48 Développement Java - XML XPath Sans XPath Sans XPath • avec DOM, utiliser : • getElementsByTagName • getElementById • avec SAX : • startElement • endElement 28 / 48 Développement Java - XML XPath Librairies XPath Librairies • Saxon 6.5.x (XPath 2.0) • Xalan-J Apache (XPath 1.0) • Jaxen http ://jaxen.org/ • depuis J2SE 5.0 (Tiger), API standard javax.xml.xpath (XPath 1.0) 29 / 48 Développement Java - XML XPath Utilitaires sous Ubuntu Sous Ubuntu installer le package libxml-xpath-perl qui contient le binaire xpath que l’on peut utiliser depuis le terminal : • xpath -e "//person/first-name" persons.xml 30 / 48 Développement Java - XML XPath Expressions XPath Sélection des noeuds expression / //balise . .. @ signification racine du document tous les noeuds qui correspondent à la balise noeud courant noeud parent sélection d’attribut 31 / 48 Développement Java - XML XPath Exemple Expression XPath Exemple • /person/first-name : tous les noeuds prénoms des personnes • //first-name : tous les noeuds prénoms • //first-name/.. : tous les noeuds person • //@id : tous les noeuds qui contiennent un attribut id 32 / 48 Développement Java - XML XPath Prédicats XPath Sélection spécifique //person[...] prédicat 1 last() last()-1 position()<3 @id=2 salary > 3000 signification la première personne la dernière personne l’avant-dernière personne les 2 premières personnes la personne d’identifiant égal à 2 les personnes de salaire > 3000 33 / 48 Développement Java - XML XPath Les fonctions XPath Fonctions • nombres : +, -, *, div, mod, sum, ceiling, floor, round • booléens : true, false, not • chaı̂nes : concat, substring, translate, normalize-space, string-length, contains, starts-with • noeuds : count, position, last 34 / 48 Développement Java - XML XPath Exemple fonction XPath Exemple • count(//person) : nombre de personnes • sum(//person/salary) div count(//person) : moyenne des salaires • //person[ not(number(salary) > (preceding-sibling::person/salary | following-sibling::person/salary)) ] : personne de salaire minimum 35 / 48 Développement Java - XML XPath Sélection de plusieurs chemins Sélection de chemins On utilise | pour séparer les chemins : //person[salary > 3000] | //first-name : donnera 3 noeuds first-name et deux noeuds person 36 / 48 Développement Java - XML XPath XPath et DOM Avec DOM 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // doc is a DOM Document XPathFactory pathFactory=XPathFactory.newInstance(); XPath xpath = pathFactory.newXPath(); XPathExpression expr = xpath.compile("//person"); // DOM specific NodeList nList = (NodeList)expr.evaluate(doc,XPathConstants.NODESET); for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT NODE) { // your code here } } 37 / 48 Développement Java - XML XPath XPath et SAX Avec SAX 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // fileName is a String File file=new File(fileName); InputSource source = new InputSource(new FileInputStream(file)); XPathFactory fabrique = XPathFactory.newInstance(); XPath xpath = fabrique.newXPath(); XPathExpression expr = xpath.compile("//person"); // SAX specific NodeList nList = (NodeList)expr.evaluate(source, XPathConstants.NODESET); for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT NODE) { // your code here } } 38 / 48 Développement Java - XML XPath XPathExpression.evaluate XPathExpression.evaluate(source, returnType) évalue l’expression XPath en fonction du contexte • source : InputSource • returnType : QName, un parmi : • NODE, NODESET • NUMBER, BOOLEAN, STRING 39 / 48 Développement Java - XML Application Application Application 40 / 48 Développement Java - XML Application Projet projet créer un projet Java standard sous Eclipse et mettre en place la lecture d’un graphe orienté pondéré au format XML avec : • DOM • SAX mettre en place des tests paramétriques pour vérifier l’intégrité des données 41 / 48 Développement Java - XML Application Projet Classes de base : package model créer les classes suivantes pour représenter un graphe : • Vertex (String name) • Edge (Vertex initial, Vertex final, int cost) • Graph (ArrayList<Vertex> vertices, ArrayList<Edge> edges) 42 / 48 Développement Java - XML Application Format de fichier Exemple de fichier graph.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE graph SYSTEM "graph.dtd"> <graph> <vertices> <vertex>V1</vertex> <vertex>V2</vertex> <vertex>V3</vertex> </vertices> <edges> <edge initial="V1" final=" V2 " cost="4"/> <edge initial="V1" final=" V3 " /> </edges> </graph> 43 / 48 Développement Java - XML Application Format de fichier DTD pour un graphe 1 2 3 4 5 6 7 8 9 10 <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT graph (vertices, edges) > <!ELEMENT vertices (vertex+) > <!ELEMENT vertex (#PCDATA) > <!ELEMENT edges (edge*) > <!ELEMENT edge EMPTY > <!ATTLIST edge cost CDATA #IMPLIED> <!ATTLIST edge initial CDATA #REQUIRED> <!ATTLIST edge final CDATA #REQUIRED> 44 / 48 Développement Java - XML Application Projet Classes du package io créer les classes suivantes pour lire un graphe : • DOMGraphReader • SAXGraphReader ces classes implantent la méthode : Graph read(String fileName) qui retourne un graphe ou null en cas d’erreur 45 / 48 Développement Java - XML Application Projet Classe du package tests créer la classe GraphReaderTest pour tester les classes du package io : • testDOMReader() • testSAXReader() utiliser les tests paramétriques pour tester plusieurs graphes 46 / 48 Développement Java - XML Bibliographie Bibliographie Bibliographie 47 / 48 Développement Java - XML Bibliographie Bibliographie, sitographie • Processing XML with Java(TM) : A Guide to SAX, DOM, JDOM, JAXP, and TrAX, Elliotte Rusty Harold, Addison-Wesley, 2002 • Murach’s Java SE 6, Joel Murach, Andrea Steelman, Murach, 2007 • XPath 2.0 Programmer’s Reference, Michael Kay, Wrox, 2004 • www.developpez.com 48 / 48