54
XML et JAVA SAX, DOM, xmlPull…

XML et JAVA

  • Upload
    anneke

  • View
    46

  • Download
    0

Embed Size (px)

DESCRIPTION

XML et JAVA. SAX, DOM, xmlPull…. Plan. JAXP SAX DOM. SAX - Simple API for XML. spécifie des librairies qui permettent avant tout de lire un document XML, d'effectuer des traitements sur le contenu de ce dernier. SAX est un analyseur basé sur les événements. Le principe de SAX est de - PowerPoint PPT Presentation

Citation preview

Page 1: XML et JAVA

XML et JAVA

SAX, DOM, xmlPull…

Page 2: XML et JAVA

Plan

JAXP SAX DOM

Page 3: XML et JAVA

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 4: XML et JAVA

SAX - Simple API for XML

spécifie des librairies qui permettent avant tout de lire un document XML, d'effectuer des traitements sur le contenu de ce

dernier.

SAX est un analyseur basé sur les événements. Le principe de SAX est de

parcourir le document XML, SAX génère des événements en fonction des éléments qui

le constitue.

Page 5: XML et JAVA

Interprétation via SAX

Page 6: XML et JAVA

SAX

L’analyseur encapsule un objet SAXReader (XMLReader). Invocation de la méthode parse() Invocation des méthodes callback implémentées par l’application. Méthodes de callback définies par les interfaces

ContentHandler : notifications reliées au contenu logique du document ErrorHandler : notifications reliées aux erreurs DTDHandler : notifications reliées à la validation EntityResolver : pour résoudre les valeurs liées à des entités externes (DB…)

Page 7: XML et JAVA

Packages principaux liés à XML

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 8: XML et JAVA

Package principaux reliés à SAX

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 9: XML et JAVA

public abstract interface ContentHandler

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 10: XML et JAVA

La classe Echo03

import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser;

public class Echo03 extends DefaultHandler {

static private Writer out; private String indentString = " "; // Amount to indent private int indentLevel = 0;

Page 11: XML et JAVA

Version SAX 1.0public static void main(String argv[]) { if (argv.length != 1) {

System.err.println("Usage: cmd filename"); System.exit(1); }

// Use an instance of ourselves as the SAX event handler DefaultHandler handler = new Echo01();

// Use the default (non-validating) parser SAXParserFactory factory = SAXParserFactory.newInstance();

try { // Set up output stream out = new OutputStreamWriter(System.out, "UTF8"); // Parse the input SAXParser saxParser = factory.newSAXParser(); saxParser.parse( new File(argv[0]), handler);

} catch (Throwable t) {

t.printStackTrace(); } System.exit(0); }

Page 12: XML et JAVA

Version SAX2.0

public static void main(String argv[]) { if (argv.length != 1) {

System.err.println("Usage: cmd filename"); System.exit(1); }

// Use an instance of ourselves as the SAX event handler DefaultHandler handler = new Echo01();

try { // Set up output stream out = new OutputStreamWriter(System.out, "UTF8");

// Use the default (non-validating) parser XMLReader saxParser = XMLReaderFactory.createXMLReader();saxParser.setContentHandler(handler); saxParser.setErrorHandler(handler); // Parse the input saxParser.parse( new File(argv[0]));

} catch (Throwable t) {

t.printStackTrace(); } System.exit(0); }

Page 13: XML et JAVA

Evénements de début et de fin de documents //=========================================================== // SAX DocumentHandler methods //===========================================================

public void startDocument() throws SAXException { nl(); nl(); emit("START DOCUMENT"); nl(); emit("<?xml version='1.0' encoding='UTF-8'?>"); }

public void endDocument() throws SAXException { nl(); emit("END DOCUMENT"); try { nl(); out.flush(); } catch (IOException e) { throw new SAXException("I/O error", e); } }

Page 14: XML et JAVA

Début d’un élément public void startElement(String namespaceURI, String lName, // local name String qName, // qualified name Attributes attrs) throws SAXException { indentLevel++; nl(); emit("ELEMENT: "); String eName = lName; // element name if ("".equals(eName)) eName = qName; // namespaceAware = false emit("<"+eName); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String aName = attrs.getLocalName(i); // Attr name if ("".equals(aName)) aName = attrs.getQName(i); nl(); emit(" ATTR: "); emit(aName); emit("\t\""); emit(attrs.getValue(i)); emit("\""); } } if (attrs.getLength() > 0) nl(); emit(">"); }

Page 15: XML et JAVA

Fin d’un élément

public void endElement( String namespaceURI, String sName, // simple name String qName // qualified name ) throws SAXException { nl(); emit("END_ELM: "); emit("</"+sName+">"); indentLevel--; }

Page 16: XML et JAVA

Echo des caractères

public void characters(char buf[], int offset, int len)

throws SAXException

{

nl(); emit("CHARS: ");

String s = new String(buf, offset, len);

if (!s.trim().equals("")) emit(s);

}

Page 17: XML et JAVA

Tracer les appels callback

Les erreurs d’I/O sont encapsulées dans une exception SAXException avec un message qui identifie l’erreur Cette exception est renvoyée à l’analyseur SAX

static private Writer out;

private void emit(String s)throws SAXException{ try { out.write(s); out.flush(); } catch (IOException e) { throw new SAXException("I/O error", e); }}

Page 18: XML et JAVA

Mise en page

// Start a new line // and indent the next line appropriately

private void nl() throws SAXException { String lineEnd = System.getProperty("line.separator"); try { out.write(lineEnd); } catch (IOException e) { throw new SAXException("I/O error", e); } }

Page 19: XML et JAVA

Exemple de fichier en entrée<?xml version='1.0' encoding='utf-8'?>

<!-- A SAMPLE set of slides -->

<slideshow title="Sample Slide Show" date="Date of publication" author="Yours Truly" >

<!-- TITLE SLIDE --> <slide type="all"> <title>Wake up to WonderWidgets!</title> </slide>

<!-- OVERVIEW --> <slide type="all"> <title>Overview</title> <item>Why <em>WonderWidgets</em> are great</item> <item/> <item>Who <em>buys</em> WonderWidgets</item> </slide>

</slideshow>

Page 20: XML et JAVA

Exemple de sortie

Page 21: XML et JAVA

Gestion des erreurs

public static void main(String argv[]) { if (argv.length != 1) { System.err.println("Usage: cmd filename"); System.exit(1); } // Use an instance of ourselves as the SAX event handler DefaultHandler handler = new Echo07(); // Use the default (non-validating) parser SAXParserFactory factory = SAXParserFactory.newInstance(); try { // Set up output stream out = new OutputStreamWriter(System.out, "UTF8");

// Parse the input SAXParser saxParser = factory.newSAXParser(); saxParser.parse( new File(argv[0]), handler);

} catch (SAXParseException spe) { ...

} catch (SAXException sxe) { ...

} catch (ParserConfigurationException pce) { ...

} catch (IOException ioe) { ... } System.exit(0); }

Page 22: XML et JAVA

Gestion des erreurspublic static void main(String argv[]) { try { } catch (SAXParseException spe) { // Error generated by the parser System.out.println("\n** Parsing error » + ", line " + spe.getLineNumber() + ", uri " + spe.getSystemId()); System.out.println(" " + spe.getMessage() );

// Use the contained exception, if any Exception x = spe; if (spe.getException() != null) x = spe.getException(); x.printStackTrace();

} catch (SAXException sxe) { // Error generated by this application (or a parser-initialization error) Exception x = sxe; if (sxe.getException() != null) x = sxe.getException(); x.printStackTrace();

} catch (ParserConfigurationException pce) { // Parser with specified options can't be built pce.printStackTrace();

} catch (IOException ioe) { // I/O error ioe.printStackTrace(); } System.exit(0); }

Page 23: XML et JAVA

Gestion des erreurs

//=========================================================== // SAX ErrorHandler methods //===========================================================

// treat validation errors as fatal public void error(SAXParseException e) throws SAXParseException { throw e; }

// dump warnings too public void warning(SAXParseException err) throws SAXParseException { System.out.println("** Warning" + ", line " + err.getLineNumber() + ", uri " + err.getSystemId()); System.out.println(" " + err.getMessage()); }

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 24: XML et JAVA

SAX : Avantages et inconvénients Avantages

SAX est capable de traiter des fichiers XML de très grande taille, n'opère pas de représentation en mémoire de la structure XML, applique des traitements au fil de la lecture de la structure.

SAX est bien adapté à des fonctionnalités de sélection d'informations précises dans un document XML. extraire certaines parties de document effectuer des totaux sur tous les enregistrements.

L'intégration de l'API SAX dans un programme Java est vraiment très simple.

Inconvénients SAX ne permet pas de modifier un document XML

Puisque le fichier XML est traité au fur et à mesure de la lecture, on ne peut pas effectuer d'accès direct à un élément particulier.

Page 25: XML et JAVA

DOM : Document Object Model Crée un arbre où chaque noeud contient une composantes

d’une structure XML

Les noeuds les plus courants sont Noeud Élément Noeud Texte

Fonctions Création et ajout d’un noeud Suppression d’un noeud Modification d’un noeud Parcours de la hiérarchie

Packages utiles org.w3c.dom javax.xml.parsers Javax.xml.transform

Page 26: XML et JAVA

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 27: XML et JAVA

Déclarations

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException;

import java.io.File;import java.io.IOException;

import org.w3c.dom.Document;import org.w3c.dom.DOMException;

public class DomEcho01{

// Global value so it can be ref'd by the tree-adapter static Document document;

Page 28: XML et JAVA

public static void main(String argv[]) { if (argv.length != 1) {

System.err.println("Usage: java DomEcho filename"); System.exit(1); }

DocumentBuilderFactory factory =

DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setNamespaceAware(true); try {

DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse( new File(argv[0]) );

} catch (SAXException sxe) { // Error generated during parsing)

Exception x = sxe; if (sxe.getException() != null) x = sxe.getException(); x.printStackTrace();

} catch (ParserConfigurationException pce) {

// Parser with specified options can't be built pce.printStackTrace();

} catch (IOException ioe) { // I/O error

ioe.printStackTrace(); }

} // main

Page 29: XML et JAVA

Gestion des erreurs

builder.setErrorHandler( new org.xml.sax.ErrorHandler() { // ignore fatal errors (an exception is guaranteed) public void fatalError(SAXParseException exception) throws SAXException { }

// treat validation errors as fatal public void error(SAXParseException e) throws SAXParseException { throw e; }

// dump warnings too public void warning(SAXParseException err) throws SAXParseException { System.out.println("** Warning" + ", line " + err.getLineNumber() + ", uri " + err.getSystemId()); System.out.println(" " + err.getMessage()); } });

Page 30: XML et JAVA

DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = fact.newDocumentBuilder();

Document doc = builder.parse(str);

// Get root

Node node = doc.getDocumentElement();

String root = node.getNodeName();

System.out.println("Root Node: " + root);

// Get a list of all elements in the document

NodeList list = doc.getElementsByTagName("*");

System.out.println("XML Elements: ");

for (int i=0; i<list.getLength(); i++) {

// Get element

Element element = (Element)list.item(i);

System.out.println(element.getNodeName());

}

Page 31: XML et JAVA

Création d’un document XMLclass CreateDomXml { public static void main(String[] args) { try{ //Create instance of DocumentBuilderFactory DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //Get the DocumentBuilder DocumentBuilder docBuilder = factory.newDocumentBuilder();

//Create blank DOM Document Document doc = docBuilder.newDocument();

//create the root element and add it to the xml tree Element root = doc.createElement("root"); doc.appendChild(root); //create a comment and add it in the root element Comment comment = doc.createComment("This is comment"); root.appendChild(comment);

//create child element and add the atribute to the child Element childElement = doc.createElement("Child"); childElement.setAttribute("attribute1","The value of Attribute 1"); root.appendChild(childElement);

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 32: XML et JAVA

Afficher le document XML sur la console

TransformerFactory tranFactory = TransformerFactory.newInstance();

Transformer aTransformer = tranFactory.newTransformer();

Source src = new DOMSource(doc);

Result dest = new StreamResult(System.out);

aTransformer.transform(src, dest);

}catch(Exception e){

System.out.println(e.getMessage());

}

}

}

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 33: XML et JAVA

XML et les applications mobiles

XML Temps de traitement bande passante requise

CLDC Un analyseur XML avec une petite empreinte

kXML• Supporte SAX et kDOM

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 34: XML et JAVA

SAX vs XmlPull

SAX « Push-based »

Quand l’analyseur est démarré, les événéements sont « poussés » en continu

Les programmeurs n’ont pas de contrôle sur le flot du processus d’analyse

Par exemple, on ne peut pas arrêter l’analyse une fois que l’on a trouvé l’élément qui nous intéresse

XmlPull Donne plus de contrôle sur l’analyse

XmlPullParser next() : START_TAG, TEXT, END_TAG, END_DOCUMENT

• nextToken() : next() + COMMENT, CDSECT, DOCDECL, ENTITY_REF, PROCESSING_INSTRUCTION, IGNORABLE_WHITESPACE

Page 35: XML et JAVA

Services Web de Amazon

Service web SOAP standard SOAP RPC

Service XML « littéral » La requête est encodée en paramètres

dans un URL

Page 36: XML et JAVA

www.amazon.com/webservicesQuickTime™ et un

décompresseur TIFF (LZW)sont requis pour visionner cette image.

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 37: XML et JAVA

Identification et sécurité

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

QuickTime™ et undécompresseur TIFF (LZW)

sont requis pour visionner cette image.

Page 39: XML et JAVA

<?xml version="1.0" ?><?xml-stylesheet type="text/xsl" href="amazon.xsl"?><ProductInfo>

<Details url="http://www.amazon.com/exec/obidos/...">

<Asin>0380977427</Asin><ProductName>Quicksilver (The Baroque Cycle, Vol. 1)</ProductName><Catalog>Book</Catalog>

<Authors><Author>Neal Stephenson</Author>

</Authors><ReleaseDate>23 September, 2003</ReleaseDate><Manufacturer>William Morrow</Manufacturer>

<ImageUrlSmall>http://images.amazon…jpg</ImageUrlSmall>

<ImageUrlMedium>http://images.amazon.com/images/…jpg</ImageUrlMedium>

<ImageUrlLarge>http://images.amazon....jpg</ImageUrlLarge>

<Availability>Usually ships within 24 hours</Availability><ListPrice>$27.95</ListPrice><OurPrice>$19.01</OurPrice><UsedPrice>$16.92</UsedPrice>

</Details></ProductInfo>

Page 40: XML et JAVA

public class AmazonLite extends MIDlet implements CommandListener {

Display display; Command pullCommand; Command kdomCommand; Command exitCommand; Command doneCommand; TextField textField;

static String token;

public AmazonLite () { display = Display.getDisplay(this); pullCommand = new Command("PULL", Command.SCREEN, 1); kdomCommand = new Command("kDOM", Command.SCREEN, 1); exitCommand = new Command("EXIT", Command.EXIT, 1); doneCommand = new Command("DONE", Command.CANCEL, 1);

// Get value from the JAD file token = getAppProperty("AmazonToken"); }

Page 41: XML et JAVA

public void startApp() { Form form = new Form("Amazon Search"); textField = new TextField ("Keywords:", "", 80, TextField.ANY); form.append( textField ); form.addCommand(exitCommand); form.addCommand(pullCommand); form.addCommand(kdomCommand); form.setCommandListener( (CommandListener) this); display.setCurrent(form); } public void pauseApp() { } public void destroyApp(boolean unconditional) { }

Page 42: XML et JAVA

public void commandAction(Command command, Displayable screen) { if (command == exitCommand) { destroyApp(false); notifyDestroyed(); } else if ( command == doneCommand ) { startApp ();

} else if ( command == pullCommand || command == kdomCommand) { // In real production system, we should put // all network and parsing tasks in a seperate // thread. I put all here for simplicity.

String keywords = textField.getString(); keywords = keywords.trim(); if ( "".equals(keywords) ) { Alert a = new Alert("Blank search string"); a.setString("Please enter one or more keywords"); a.setTimeout(Alert.FOREVER); display.setCurrent(a); return; }

Page 43: XML et JAVA

Lancer la requête et analyser la réponse keywords = WSencode(keywords);

String url = "http://xml.amazon.com/onca/xml?v=1.0" + "&t=webservices-20&dev-t=" + token + "&KeywordSearch=" + keywords + "&mode=books&type=lite&page=1&f=xml";

Vector books = new Vector (); try { HttpConnection conn = (HttpConnection) Connector.open (url); conn.setRequestMethod(HttpConnection.GET); InputStream is = conn.openInputStream ();

if ( command == pullCommand ) { books = getBooksViaPull( is ); } else { books = getBooksViaDOM( is ); }

is.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); }

Page 44: XML et JAVA

Afficher le résultat

Form form = new Form("Results"); for (int i = 0; i < books.size(); i++) { BookDetails bd = (BookDetails) books.elementAt(i); form.append("\"" + bd.title + "\" "); form.append("By " + bd.firstAuthor + "\n"); form.append("Amazon price " + bd.newPrice + "\n"); form.append("Used price " + bd.usedPrice + "\n"); form.append(bd.url + "\n\n"); } form.addCommand(doneCommand); form.setCommandListener( (CommandListener) this); display.setCurrent(form); } else { // Do nothing } }

Page 45: XML et JAVA

Ajuster les mots-clés pour transmission http // Get rid of excessive white spaces and replace significant // white spaces with %20 String WSencode(String s) { StringBuffer buf = new StringBuffer (); int len = s.length(); boolean blank = false; for (int i = 0; i < len; i++) { if ( s.charAt(i) == ' ' ) { if ( !blank ) { buf.append("%20"); blank = true; } } else { buf.append( s.charAt(i) ); blank = false; } } return buf.toString(); }

Page 46: XML et JAVA

Vector getBooksViaDOM (InputStream is) throws Exception { Vector books = new Vector ();

InputStreamReader reader = new InputStreamReader(is); KXmlParser parser = new KXmlParser(); parser.setInput(reader);

Document doc = new Document (); doc.parse (parser);

// The <ProductInfo> element Element prods = doc.getRootElement();

int numOfEntries = prods.getChildCount (); for (int i = 0; i < numOfEntries; i++) { if ( prods.isText(i) ) { // Text here are all insignificant white spaces. // We are only interested in children elements } else { // Not text, must be a <Details> element Element e = prods.getElement (i); BookDetails bd = getBookDetailsViaDOM( e ); books.addElement( bd ); } } return books; }

Page 47: XML et JAVA

BookDetails getBookDetailsViaDOM (Element e) throws Exception { BookDetails bd = new BookDetails (); // get attribute value from the <Details> start tag bd.url = e.getAttributeValue(null, "url"); int numOfChildren = e.getChildCount (); for (int i = 0; i < numOfChildren; i++) { if ( e.isText(i) ) { // Ignore } else { Element c = e.getElement(i); String tagname = c.getName(); if ( tagname.equals("ProductName") ) { // First child is a text node bd.title = c.getText(0).trim(); } if ( tagname.equals("Authors") ) { // Goes down the tree: The second child is the // first <Author> element. Get the first child of // that element. bd.firstAuthor = c.getElement(1).getText(0).trim(); }

Page 48: XML et JAVA

BookDetails getBookDetailsViaDOM (Element e) throws Exception {...if ( tagname.equals("OurPrice") ) { // First child is a text node bd.newPrice = c.getText(0).trim(); } if ( tagname.equals("UsedPrice") ) { // First child is a text node bd.usedPrice = c.getText(0).trim(); } } } return bd; }

Page 49: XML et JAVA

Vector getBooksViaPull (InputStream is) throws Exception { Vector books = new Vector ();

InputStreamReader reader = new InputStreamReader(is); KXmlParser parser = new KXmlParser(); parser.setInput(reader);

int eventType = parser.getEventType(); while (eventType != parser.END_DOCUMENT) { // Only respond to the <Details> start tag if (eventType == parser.START_TAG) { if ( parser.getName().equals("Details") ) { BookDetails bd = getBookDetailsViaPull(parser); books.addElement( bd ); } } eventType = parser.next(); } return books; }

Page 50: XML et JAVA

BookDetails getBookDetailsViaPull (XmlPullParser parser)

throws Exception {

BookDetails bd = new BookDetails ();

// get attribute value from the <Details> start tag

bd.url = parser.getAttributeValue(null, "url");

int eventType = parser.next();

while ( true ) {

// Break out the loop at </Details> end tag

if ( eventType == parser.END_TAG ) {

if ( parser.getName().equals("Details") ) {

break;

}

}

...

Page 51: XML et JAVA

BookDetails getBookDetailsViaPull (XmlPullParser parser) throws Exception {... if ( eventType == parser.START_TAG ) { String tagname = parser.getName(); if ( tagname.equals("ProductName") ) { // Proceed to the enclosed Text node parser.next(); bd.title = parser.getText().trim(); } if ( tagname.equals("Authors") ) { // First <Author> start tag parser.next(); // White space between tags parser.next(); // Proceed to the enclosed Text node parser.next(); bd.firstAuthor = parser.getText().trim(); }...

Page 52: XML et JAVA

BookDetails getBookDetailsViaPull (XmlPullParser parser) throws Exception {... if ( tagname.equals("OurPrice") ) { // Proceed to the enclosed Text node parser.next(); bd.newPrice = parser.getText().trim(); } if ( tagname.equals("UsedPrice") ) { // Proceed to the enclosed Text node parser.next(); bd.usedPrice = parser.getText().trim(); } } eventType = parser.next(); } return bd; }

Page 53: XML et JAVA

class BookDetails {

String url; String title; String firstAuthor; String newPrice; String usedPrice;

public BookDetails () { url = "http://unknown"; title = "undefined"; firstAuthor = "unknown"; newPrice = "unknown"; usedPrice = "unknown"; }

}

Page 54: XML et JAVA

Références

Working with XML

http://java.sun.com/xml/jaxp/dist/1.1/docs/tutorial/overview/1_xml.html

Part II: Serial Access with the Simple API for XML (SAX) http://java.sun.com/webservices/jaxp/dist/1.1/docs/tutorial/sax/index.html http://java.sun.com/webservices/jaxp/dist/1.

1/docs/tutorial/sax/work/Echo03.java http://java.sun.com/webservices/jaxp/dist/1.1/docs/tutorial/sax/2a_echo

.html

Part III: XML and the Document Object Model (DOM) http://java.sun.com/webservices/jaxp/dist/1.1/docs/tutorial/dom/index.html