Java & XML
SAX (Simple API for XML)
référence : http://www.saxproject.org.
Auteur : David Megginson.
Version : 2.0.1.
L'interface de programmation SAX propose une vision événementielle de l'analyse d'un document XML.
Principes de SAX

Objectifs :
- Simplifier l'accès aux analyseurs,
- Rendre l'application indépendante des analyseurs,
L'analyse génère des évènements récupérés par SAX et passés à l'application.
Les packages Java de SAX 2
Les interfaces du package org.xml.sax:
ContentHandler évènements liés au contenu DTDHandler évènements liés à la DTD ErrorHandler récupération des erreurs Locator récupération de la position XMLReader Analyseur | XMLFilter AttributeList Attributes EntityResolver ...
Les classes du package org.xml.sax.helpers:
org.xml.sax.helpers.DefaultHandler implements org.xml.sax.ContentHandler, implements org.xml.sax.DTDHandler, implements org.xml.sax.EntityResolver, implements org.xml.sax.ErrorHandler ...
Premier programme SAX2
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
public class Essai extends DefaultHandler {
public Essai () { super(); }
public static void main (String args[]) throws Exception {
// Analyseur Xerces par défaut (Java 5)
XMLReader xr = XMLReaderFactory.createXMLReader();
Essai handler = new Essai();
xr.setContentHandler(handler);
xr.setErrorHandler(handler);
// xr.setDTDHandler(handler);
xr.setFeature("http://xml.org/sax/features/validation", true);
xr.parse(new InputSource(args[0]));
}
Le gestionnaire de contenu
public void startDocument () {
System.out.println("Start document");
}
public void endDocument () {
System.out.println("End document");
}
public void startElement (
String uri,
String name,
String qName,
Attributes atts
) {
System.out.println("Start element: {" + uri + "}" + name);
}
public void endElement (String uri, String name, String qName) {
System.out.println("End element: {" + uri + "}" + name);
}
Traiter les caractères
public void characters (char ch[], int start, int length) {
System.out.print("Characters: \"");
for (int i = start; i < start + length; i++) {
switch (ch[i]) {
case '\\': System.out.print("\\\\"); break;
case '"': System.out.print("\\\""); break;
case '\n': System.out.print("\\n"); break;
case '\r': System.out.print("\\r"); break;
case '\t': System.out.print("\\t"); break;
default: System.out.print(ch[i]); break;
}
}
System.out.print("\"\n");
}
Traiter les erreurs
public void error(SAXParseException e) {
System.err.println("Erreur non fatale (ligne " +
e.getLineNumber() + ", col " +
e.getColumnNumber() + ") : " + e.getMessage());
}
public void fatalError(SAXParseException e) {
System.err.println("Erreur fatale : " + e.getMessage());
}
public void warning(SAXParseException e) {
System.err.println("warning : " + e.getMessage());
}
L'API DOM (Document Object Model)

♦ Représentation Objet en mémoire d'un document XML ou HTML (4.0).
♦ C'est une norme proposée par le consortium W3C (http://www.w3.org/DOM/) pour résoudre les problèmes liées au DHTML (HTML + CSS + JavaScript).
♦ Le DOM se compose de deux parties:
- DOM noyau (Core DOM) pour XML,
- DOM HTML.
Le package Java org.w3c.dom
Les interfaces du package org.w3c.dom:
Node | Attr | CharacterData | | Comment | | Text | | | CDATASection | Document | DocumentFragment | DocumentType | Element | Entity | EntityReference | Notation | ProcessingInstruction NamedNodeMap NodeList ...
L'interface org.w3c.dom.Node
Les méthodes de l'interface org.w3c.dom.Node:
Node getFirstChild() Node getNextSibling() Node getLastChild() Node getPreviousSibling() Node getParentNode() NodeList getChildNodes() boolean hasChildNodes() Document getOwnerDocument() NamedNodeMap getAttributes() boolean hasAttributes() String getLocalName() String getNamespaceURI() String getNodeName() String getPrefix() short getNodeType() String getNodeValue()
Méthodes de modification :
Node appendChild(Node newChild) Node insertBefore(Node newChild, Node refChild) Node removeChild(Node oldChild) Node replaceChild(Node newChild, Node oldChild) void setNodeValue(String nodeValue) void setPrefix(String prefix) Node cloneNode(boolean deep) ...
Premier programme DOM
Déclaration de l'analyseur XML et création du document:
import org.w3c.dom.*;
import java.io.*;
public class Exemple {
public static void main(String[] args) throws Exception {
Document doc;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(new File(args[0]));
afficher("", doc);
}
...
Parcours d'un arbre DOM
Parcours de l'arbre XML :
public static void afficher(String indent, Node n) {
if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
System.out.println(indent + n.getNodeValue() );
}
else if (n instanceof Comment) {
System.out.println(indent + "<!--" + n.getNodeValue() + " -->");
}
else if (n instanceof Element) {
Element e = ((Element) n);
System.out.println(indent + "<" + e.getTagName() + ">");
NodeList fils = n.getChildNodes();
for(int i=0; (i < fils.getLength()); i++) {
afficher(indent + " | ", fils.item(i));
}
System.out.println(indent + "</" + e.getTagName() + ">");
}
else if (n instanceof Document) {
NodeList fils = n.getChildNodes();
for(int i=0; (i < fils.getLength()); i++) {
afficher(indent, fils.item(i));
}
}
}
JAXP (Java API for XML Processing)

proposé par JavaSoft (http://java.sun.com/xml/jaxp/) et présent depuis java2 version 1.4.
Unification des approches SAX & DOM
Proposition d'une API standard pour les transformations de documents XML (processeur XSL, FO et/ou XPATH).
Une usine à analyseurs
Le package javax.xml.parsers propose les classes
DocumentBuilderFactory producteur d'analyseurs DOM SAXParserFactory producteur d'analyseurs SAX DocumentBuilder Analyseur DOM SAXParser Analyseur SAX ...
Quelques méthodes de DocumentBuilderFactory :
static DocumentBuilderFactory newInstance()
... ...
boolean isValidating()
void setValidating(boolean validating)
... ...
DocumentBuilder newDocumentBuilder()
Quelques méthodes de SAXParserFactory :
static SAXParserFactory newInstance()
... ...
DocumentBuilder newDocumentBuilder()
SAXParser newSAXParser()
Les analyseurs JAXP
Les usines servent à produire des analyseurs ayant certaines caractéristiques.
Quelques méthodes de DocumentBuilder:
Document parse(java.io.File f)
Document parse(org.xml.sax.InputSource is)
Document parse(java.io.InputStream is)
Document parse(java.lang.String uri)
... ...
void setErrorHandler(org.xml.sax.ErrorHandler eh)
... ...
Quelques méthodes de SAXParser:
org.xml.sax.XMLReader getXMLReader()
... ...
void parse(java.io.File f, DefaultHandler dh)
void parse(InputSource is, DefaultHandler dh)
void parse(java.io.InputStream is, DefaultHandler dh)
void parse(java.lang.String uri, DefaultHandler dh)
Une usine pour transformer
Le package javax.xml.transform propose les classes
TransformerFactory Fabrication des transformations Transformer Une transformation OutputKeys Le format de sortie d'une transformation
Quelques méthodes de TransformerFactory:
static TransformerFactory newInstance()
... ...
Transformer newTransformer()
Transformer newTransformer(Source source)
... ...
Templates newTemplates(Source source)
Une Source peut être:
- javax.xml.transform.dom.DOMSource,
- javax.xml.transform.sax.SAXSource,
- javax.xml.transform.stream.StreamSource,
Les transformations
Quelques méthodes de Transformer:
void setOutputProperty(String name, String value) void setParameter(String name, java.lang.Object value) ... ... void transform(Source xmlSource, Result outputTarget) ... ...
Un Result peut être:
- javax.xml.transform.dom.DOMResult,
- javax.xml.transform.sax.SAXResult,
- javax.xml.transform.stream.StreamResult,
Un exemple de transformation
Lecture, copie et sérialisation :
// Créer une usine à "transformer"
TransformerFactory factory = TransformerFactory.newInstance();
// Un premier "transformer" simple
Transformer analyseur = factory.newTransformer();
// Lire le document XML et en faire une copie
DOMResult xml = new DOMResult();
analyseur.transform(new StreamSource("test.xml"), xml);
DOMSource xmlSrc = new DOMSource(xml.getNode());
analyseur.transform(xmlSrc, new StreamResult("test2.xml") );
Utilisation d'une feuille de style XSLT :
// Un "transformer" processeur XSL
Transformer xslt = factory.newTransformer( new StreamSource("test.xsl") );
// appliquer la feuille XSLT
DOMResult out = new DOMResult();
xslt.transform(new DOMSource(xml.getNode()), out);
// Serialiser out dans "test.out" en iso-8859-1
analyseur.setOutputProperty(OutputKeys.INDENT, "yes");
analyseur.setOutputProperty(OutputKeys.ENCODING, "iso-8859-1");
analyseur.transform(
new DOMSource(out.getNode()),
new StreamResult("test.out")
);
Les alternatives à SAX/DOM/JAXP
La librairie JDOM
Objectifs : offrir une bibliothèque simple pour la représentation et la manipulation de documents XML (http://www.jdom.org).
import org.jdom.Element;
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
public static void main(String[] args)
{
Element stock = new Element("stock")
.addContent(new Element("nom").setText("CD"))
.addContent(new Element("prix").setText("100"));
Document root = new Document(stock);
XMLOutputter outputter = new XMLOutputter(" ",true,"iso-8859-1");
try { outputter.output(root, System.out); }
catch (java.io.IOException e) { }
}
Des passerelles sont disponibles vers :
- la représentation DOM,
- les évènements SAX,
- les analyseurs compatibles SAX/DOM,
- les processeurs XSL compatibles JAXP,
La librairie DOM4J
Une autre librairie qui utilise XPATH (http://www.dom4j.org).
import java.util.*;
import org.dom4j.Document; import org.dom4j.DocumentHelper;
import org.dom4j.Element;
public class Dom4jSample {
public static void main(String args[]) {
Document document = DocumentHelper.createDocument();
Element root = document.addElement( "root" );
Element author2 = root.addElement( "author" )
.addAttribute( "id", "Toby" ).addAttribute( "location", "Germany" )
.addText( "Tobias Rademacher" );
Element author1 = root.addElement( "author" )
.addAttribute( "id", "James" ).addAttribute( "location", "UK" )
.addText( "James Strachan" );
List results = document.selectNodes("//author[@location = 'UK']");
for ( Iterator iter = results.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
System.out.println(element.valueOf("concat(@id,' : ', .)"));
}
}
}
JAXB (Java API for XML Binding)
Objectif : mise en correspondance (binding) automatique entre une famille de documents XML et un schéma de classes Java.
Continuité entre :
- une analyse UML,
- un diagramme de classes,
- un modèle physique sous la forme d'un Schéma XML,
- une implantation Java automatisée.
Compilation d'un DTD/schéma

à partir de la DTD suivante (et/ou du schéma) :
<!ELEMENT personne (nom,age,adresse)> <!ELEMENT nom (#PCDATA)> <!ELEMENT age (#PCDATA)> <!ELEMENT adresse (rue,ville)> <!ELEMENT rue (#PCDATA)> <!ELEMENT ville (#PCDATA)>
nous obtenons
interface Personne { | interface Adresse {
String getNom(); | String getRue();
int getAge(); | String getVille();
Adresse getAdresse(); | }
} |
Lecture d'un fichier XML

En une seule opération le fichier XML peut être
- analysé,
- validé et
- chargé en mémoire sous la forme d'instances des classes générées.
Génération de documents XML

♦ Ce mécanisme est la base de la persistance d'objet implantée dans les EJB ou les JDO (Java data Object).
♦ Il existe d'autres framework de mise en correspondance XML-Java comme
- castor (http://www.castor.org/),
- breeze (http://www.breezefactor.com/),
- XGen (http://www.commerceone.com/),