1 / 54

XML et JAVA

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

anneke
Download Presentation

XML et JAVA

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. XML et JAVA SAX, DOM, xmlPull…

  2. Plan • JAXP • SAX • DOM

  3. 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.

  4. Interprétation via SAX

  5. 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…)

  6. Packages principaux liés à XML

  7. Package principaux reliés à SAX

  8. public abstract interface ContentHandler

  9. 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;

  10. Version SAX 1.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(); // 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); }

  11. 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); }

  12. 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); } }

  13. 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(">"); }

  14. 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--; }

  15. 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); }

  16. 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); } }

  17. 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); } }

  18. 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>

  19. Exemple de sortie

  20. 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); }

  21. Gestion des erreurs public 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); }

  22. 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()); }

  23. 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.

  24. 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

  25. 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;

  26. 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

  27. 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()); } } );

  28. 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()); }

  29. Création d’un document XML class 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);

  30. 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()); } } }

  31. 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

  32. 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

  33. 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

  34. www.amazon.com/webservices

  35. Identification et sécurité

  36. http://xml.amazon.com/onca/xml? v1.0 &t=webservices-20&dev-t=1Z644CSSBHC &KeywordSearch=mobile%20Java &mode=books&type=lite&page=1&f=xml

  37. <?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>

  38. 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"); }

  39. 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) { }

  40. 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; }

  41. 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(); }

  42. 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 } }

  43. 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(); }

  44. 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; }

  45. 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(); }

  46. 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; }

  47. 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; }

  48. 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; } } ...

More Related