1 / 50

SAX & DOM

SAX & DOM. Laurea Magistrale in Informatica Reti 2 (2005/06). dott. Francesco De Angelis francesco.deangelis@unicam.it. Agenda. Introduzione e confronto approcci SAX DOM. Introduzione e confronto approcci. Applicazione. XML parser. XSD. DTD. XML. Il parser.

violet-pope
Download Presentation

SAX & DOM

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. SAX & DOM Laurea Magistrale in Informatica Reti 2 (2005/06) dott. Francesco De Angelis francesco.deangelis@unicam.it

  2. Agenda • Introduzione e confronto approcci • SAX • DOM SAX & DOM

  3. Introduzione e confronto approcci

  4. Applicazione XML parser XSD DTD XML Il parser • Il parser si occupa di: • Recuperare il documento XML • Caricare i dati in memoria • Presentare all’applicazione un’interfaccia di alto livello • (opzionalmente) fornire servizi di validazione • (opzionalmente) fornire servizi di ricerca SAX & DOM

  5. Applicazione nome libro autore … <libro titolo=“Corso diXML“> <autore> <nome>Francesco</nome> <cognome>De Angelis</cognome> </autore> <autore> <nome>Alberto</nome> <cognome>Polzonetti</cognome> </autore> <capitolo titolo=“SAX and DOM">...</capitolo> </libro> XML Parser Approccio ad eventi • Il parser scandisce l’intero file • Per ogni elemento informa l’applicazione tramitela tecnica del callback t SAX & DOM

  6. attr libro titolo=“…” Applicazione autore nome <libro titolo=“Corso di XML“> <autore> <nome>Francesco</nome> <cognome>De Angelis</cognome> </autore> <autore> <nome>Alberto</nome> <cognome>Polzonetti</cognome> </autore> <capitolo titolo=“SAX and DOM">...</capitolo> </libro> cognome XML Parser Approccio del modello • Il parser costruisce una struttura ad albero che rappresenta il documento • Fornisce all’applicazione delle API per navigarel’albero SAX & DOM

  7. Confronto tra gli approcci SAX & DOM

  8. JAXP • Java API for XML Processing (JAXP) • Supporto standard di SUN per l’elaborazione di XML • Propone due standard per le due impostazioni: • SAX (Simple API for XML) ad eventi • DOM (Document Object Model) basato su una rappresentazione astratta in memoria SAX & DOM

  9. SAX e DOM • Anche se si ritenesse DOM come la scelta migliore per la propria applicazione Java, capire SAX è importante per vari motivi: • Il sistema di gestione degli errori del DOM è “ereditato” da SAX • Essendo SAX la prima API XML per Java, resta alla base anche dell’implementazione DOM • Le librerie Java usano SAX per leggere un file XML e creare il DOM corrispondente! SAX & DOM

  10. Simple API for XML

  11. Introduzione a SAX • SAX, o Simple API for XML, in origine è stata sviluppata come API per accedere ad XML con Java. • La homepage del progetto SAX (SourceForge) è http://www.saxproject.org/ • Basa il suo sistema di parsing sugli eventi • Inizio di un documento • Apertura e chiusura di un elemento • Apertura e chiusura di un blocco caratteri • Ingresso ed uscita dallo scope di un namespace • Caratteri, Process Instruction • Fine del documento SAX & DOM

  12. Utilità e Limiti di SAX • Il parser SAXnon costruisce documenti XML, né conserva alcuna struttura in memoria alla fine del parsing. • Se il programmatore vuole operare sul documento letto, dovrà scrivere manualmente tutto il codice, basandosi sui dati passati con gli eventi SAX. • In generale SAX necessita di molto più codice di DOM, ma è molto più leggero. • Il programmatore può implementare solo quello che è strettamente utile, e non è necessario allocare il documento in memoria. SAX & DOM

  13. Gestire gli Eventi SAX • Per ricevere le notifiche dal parser SAX, il codice deve registrare nel parser una classe org.xml.sax.DefaultHandlerche implementa l’interfacciaorg.xml.sax.ContentHandler • I vari metodi di questa interfaccia ricevono tutte le informazioni necessarie per trattare gli eventi. • Ad esempio, il metodo startElement riceve il nome dell’elemento e del suo namespace, nonché la lista degli attributi associati. SAX & DOM

  14. L’handler di SAX Interface ContentHandler { void setDocumentLocator(Locator locator); void startDocument(); void startElement(String namespaceURI,String localName, String qName, Attributes atts); void startPrefixMapping(String prefix, String uri); void characters(char[] ch, int start, int length); void endDocument(); void endElement(String namespaceURI,String localName, String qName); void endPrefixMapping(String prefix); void ignorableWhitespace(char[] ch, int start, int length); void processingInstruction(String target, String data); void skippedEntity(String name); } SAX & DOM

  15. L’handler di SAX • La classe DefaultHandler implementa l’interfaccia permettendo all’applicazione di ridefinire (override) solo i metodi desiderati public class MyHandler extends DefaultHandler { public void startElement(String namespaceURI, String localName, String qualifiedName, Attributes att) throws SAXException { System.out.println("startElement: " + qualifiedName); } public void characters(char ch[], int start, int length) throws SAXException { System.out.println("characters " + start + " to " + (start + length - 1) + ": " + new String(ch, start, length)); } public void endElement(String namespaceURI, String localName, String qualifiedName) throws SAXException { System.out.println(“endElement: /" + qualifiedName); } } SAX & DOM

  16. Utilizzo dell’handler SAX • Il client utilizza la classe di Factory per recuperare il parser • Al parser viene chiesto di “parsare” il file come un processo autonomo public class SimpleSax { public static void main(String[] args) { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); SAXParser sxp; sxp = factory.newSAXParser(); DefaultHandler handler = new SimpleHandler(); sxp.parse(new File("xml/articolo.xml").getAbsolutePath(),handler); } } SAX & DOM

  17. Gestire gli Errori SAX • Gli errori generati dal parser SAX sono incapsulati in eccezioni che però non vengono mai sollevate. • Invece, le eccezioni vengono passate a un oggetto con interfaccia ErrorHandler registrato nel parser. • Se nessun oggetto di questo tipo viene specificato dal programmatore, gli errori di parsing non vengono segnalati! • Anche il DOM usa questo modello di errore! SAX & DOM

  18. ErrorHandler Interface ErrorHandler { void error(SAXParseException exception) void fatalError(SAXParseException exception) void warning(SAXParseException exception) } Class SAXParseException { intgetColumnNumber() intgetLineNumber() StringgetPublicId() StringgetSystemId() } • La classe org.xml.sax.helpers.DefaultHandler fornisce una implementazione di default per ErrorHandler e altre interfacce utili per SAX • E’ possibile estendere questa classe per implementare più facilmente il proprio ErrorHandler SAX & DOM

  19. SAX con JAXP import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; import org.xml.sax.helpers.DefaultHandler; SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); try { SAXParser sxp = factory.newSAXParser(); } catch (javax.xml.parsers.ParserConfigurationException) { } DefaultHandler handler = new DefaultHandler(); try { sxp.parse(filename,handler); } catch (java.io.IOException ioe) { } catch (org.xml.sax.SAXParseException spe) { } catch (org.xml.sax.SAXException se) { } SAX & DOM

  20. SAX con Xerces import org.apache.xerces.parsers.SAXParser; import org.xml.sax.helpers.DefaultHandler; SAXParser sxp = new SAXParser(); try { sxp.setFeature( "http://xml.org/sax/features/validation", true ); } catch (org.xml.sax.SAXNotRecognizedException ex ) { } catch (org.xml.sax.SAXNotSupportedException ex ) { } DefaultHandler handler = new DefaultHandler(); sxp.setContentHandler(handler); sxp.setErrorHandler(handler); try { sxp.parse(filename); } catch (java.io.IOException ioe) { } catch (org.xml.sax.SAXParseException spe) { } catch (org.xml.sax.SAXException se) { } SAX & DOM

  21. Document Object Model

  22. Definizione di DOM • E’ un’API (Application Programming Interface) per documenti XML • Il DOM definisce una modalità di rappresentazione dei documenti XML accessibile da un linguaggio di programmazione, e le operazioni per la loro manipolazione SAX & DOM

  23. Definizione di DOM • Definisce le operazioni necessarie per operare sulla rappresentazione intermedia • Parsing di un file = caricamento della struttura • Costruzione di un nuovo documento • Browsing e navigazione • Aggiungere, eliminare, modificare e spostare le componenti • Specifica le operazioni indipendentemente dal linguaggio, esistono implementazioni di DOM in linguaggi differenti: • Linguaggi server-side : java, C++, C# • Linguaggi di script: VB-Script, JavaScript SAX & DOM

  24. I livelli di DOM • Livello 0 : • Funzionalità originali di Netscape / IE • NON è una raccomandazione W3C • Livello 1 – Settembre 2000: • Oggetti fondamentali per il modello DOM • navigazione di un documento DOM e manipolazione del contenuto. • Non completamente compatibile con il livello 0 • Livello 2 – Novembre 2000: • Namespace e validazione • modello ad eventi per il controllo • Livello 3 - Working Draft Febbraio 2004 • ... La specifica attuale è al Livello 2, tuttavia alcune specifiche del Livello 3 sono già raccomandazioni del W3C. SAX & DOM

  25. La struttura di DOM • DOM vede i documenti come una struttura gerarchica ad albero, composta da oggetti di tipo Node • Ogni nodo può avere uno o più figli • In realtà, la struttura è una “foresta” perché può anche contenere più alberi distinti. • Tuttavia, l’utente che accede al documento tramite l’interfaccia DOM, lo vedrà effettivamente come un albero. • Il DOM definisce solo la vista logica: non specifica come debbano essere effettivamente strutturati in memoria. SAX & DOM

  26. I modelli a oggetti • Il DOM, come modello ad oggetti, definisce: • Gli oggetti usati per rappresentare e manipolare un documento XML. • Le interfacce usate per interagire con gli oggetti definiti. • La semantica richiesta dagli oggetti e dalle interfacce definite. • Le relazioni e interazioni tra le interfacce e gli oggetti definiti. SAX & DOM

  27. La vista del DOM su XML document <song> track=9 <artist> <title> <comment> <length> <name> Corazon Espinado <minutes> <seconds> <songtrack="9"> <artist> <name>Santana</name> </artist> <title>Corazon Espinado</title> <comment>First Hit from the Album</comment> <length> <minutes>4</minutes> <seconds>36</seconds> </length> </song> Santana 4 36 First Hit from the Album SAX & DOM

  28. Caricamento di un DOM import org.w3c.dom.*; import javax.xml.parsers.*; import org.xml.sax.*; Definizione DOM standard Implementazione di JAXP DOM usa SAX DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse("libro.xml"); • Il DOM di JAXP è definito nel package org.w3c.dom • Fornisce un’interfaccia standard che si appoggia su implementazioni differenti • Sono disponibili implementazioni differenti (SUN, Apache, Oracle) • L’implementazione di SUN è in javax.xml.parsers SAX & DOM

  29. Navigazione di un DOM • Estrazione del nodo radice e stampa del nome del nodo • Nodi figli • Attributi Element root = doc.getDocumentElement(); System.out.println(root.getNodeName()); NodeList children = root.getChildNodes(); for (int i = 0; i < children.getLength(); i++) System.out.println(children.item(i).getNodeName); NamedNodeMap map = root.getAttributes(); for (int i = 0; i < map.getLength(); i++) System.out.println(map.item(i).getNodeName()); SAX & DOM

  30. Tipizzazione • Tipizzazione tramite attributi di descrizione n.getNodeType() == n.ELEMENT_NODE SAX & DOM

  31. Validazione e Namespace • Per default DOM è non validante • Una volta abilitata la validazione, questa avviene tramite il DTD • Tuttavia è possibile utilizzare XSD associando il corrispettivo namespace alla proprietà “http://java.sun.com/xml/jaxp/properties/schemaLanguage” • In maniera analoga è possibile abilitare la gestione dei namespace factory.setValidating(true); factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); factory.setNamespaceAware(true); SAX & DOM

  32. Error Handling • Eredita la gestione degli errori di SAX • l’applicazione si “registra” come listener per li eventi che segnalano un errore • Tre tipi di errori: fatali, errori semplici, warning class Handler implements ErrorHandler { public void fatalError(SAXParseException ex) throws SAXException { ex.printStackTrace(); } public void error(SAXParseException ex) throws SAXParseException { ex.printStackTrace(); throw ex; } public void warning(SAXParseException err) throws SAXParseException { System.out.println("** Warning" + err.getLineNumber() + err.getMessage()); } } builder.setErrorHandler(new Handler()); SAX & DOM

  33. Browsing e stampa public static void print(Node n, String spaces) { if (n == null) return; if (n instanceof Element) { String s = spaces + n.getNodeName() + " ("; NamedNodeMap map = n.getAttributes(); if (map != null) for (int i = 0; i < map.getLength(); i++) s += map.item(i).getNodeName() + "=" + map.item(i).getNodeValue(); s += ")"; System.out.println(s); } else if (n instanceof Text) System.out.println(spaces + n.getNodeValue()); NodeList children = n.getChildNodes(); for (int i = 0; i < children.getLength(); i++) print(children.item(i), spaces + “ – “); } Element root = doc.getDocumentElement(); print(root, “”); SAX & DOM

  34. Esempio • XML in ingresso <?xml version="1.0" encoding="ISO-8859-1"?> <libro titolo=“Corso di XML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.elet.polimi.it" xsi:schemaLocation="http://www.elet.polimi.it libro4b.xsd"> <autore> <nome>Francesco</nome> <cognome>De Angelis</cognome> </autore> <autore> <nome>Alberto</nome> <cognome>Polzonetti</cognome> </autore> <capitolo titolo=“SAX and DOM">...</capitolo> </libro> SAX & DOM

  35. Esempio • Output libro ( titolo=Corso di XML xmlns=http://www.elet.polimi.it xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation=http://www.elet.polimi.it libro3b.xsd) - autore () - - nome () - - - Francesco - - cognome () - - - De Angelis - autore () - - nome () - - - Alberto - - cognome () - - - Polzonetti - capitolo ( titolo=SAX and DOM) - - ... SAX & DOM

  36. Creazione del nodo Element root = doc.getDocumentElement(); Element cap = doc.createElement("capitolo"); cap.setAttribute("titolo", "Introduzione"); cap.appendChild(doc.createTextNode("... testo ...")); Node capitolo = doc.getElementsByTagNameNS("http://www.elet.polimi.it", "capitolo").item(0); root.insertBefore(cap, capitolo); doc.normalize(); Creazione dell’attributo Ricerca del primo capitolo presente Inserimento normalizzazione. Es: unisce nodi di testo consecutivi Modifica dell’albero • DOM permette di inserire nuovi elementi nell’albero SAX & DOM

  37. Gli oggetti Node: la base del DOM • Il DOM presenta i documenti come una struttura gerarchica di oggetti di tipo Node. • Ciascun oggetto nel documento in realtà implementa una interfaccia più specifica per il suo tipo, che è sempre derivata da Node • I Node possono avere zero o più nodi figli • L’interfaccia di Node include le operazioni di base eseguibili su ogni tipo di oggetto (indipendentemente dal suo tipo specifico) in un documento XML SAX & DOM

  38. Tipi di Nodo (nodeType) • I tipi specifici per i nodi sono identificati dalle costanti dell’interfaccia Node: • ELEMENT_NODE: il nodo è un elemento (= 1) • ATTRIBUTE_NODE: il nodo è un attributo (= 2) • TEXT_NODE: il nodo è del testo (= 3) • CDATA_SECTION_NODE: il nodo è una sezione CDATA (= 4) • ENTITY_REFERENCE_NODE: il nodo è un riferimento ad entità (= 5) • ENTITY_NODE: il nodo è un’entità (= 6) • PROCESSING_INSTRUCTION_NODE: il nodo è una PI (= 7) • COMMENT_NODE: il nodo è un commento (= 8) • DOCUMENT_NODE: il nodo è un documento (non la radice!) (= 9) • DOCUMENT_TYPE_NODE: il nodo è un DOCTYPE (= 10) • DOCUMENT_FRAGMENT_NODE: il nodo è un frammento (= 11) • NOTATION_NODE: il nodo è una NOTATION (= 12) SAX & DOM

  39. Interfaccia degli oggetti Node interface Node { const unsigned short ELEMENT_NODE = 1; //…ed altre costanti di tipo... readonly attribute DOMString nodeName; attribute DOMString nodeValue; readonly attribute unsigned short nodeType; readonly attribute Node parentNode; readonly attribute NodeList childNodes; readonly attribute Node firstChild; readonly attribute Node lastChild; readonly attribute Node previousSibling; readonly attribute Node nextSibling; readonly attribute NamedNodeMap attributes; readonly attribute Document ownerDocument; Node insertBefore(in Node newChild,in Node refChild) raises(DOMException); Node replaceChild(in Node newChild, in Node oldChild) raises(DOMException); Node removeChild(in Node oldChild) raises(DOMException); Node appendChild(in Node newChild) raises(DOMException); boolean hasChildNodes(); Node cloneNode(in boolean deep); }; SAX & DOM

  40. Semantica dei Metodi di Node • Le funzioni di Node per la manipolazione dei nodi figli sono • appendChild, • removeChild, • replaceChild, • insertBefore. • La legalità di ciascuno di questi metodi dipende dal tipo effettivo del nodo. • Nel caso l’operazione non sia disponibile (ad esempio, appendChild su un nodo Text), viene generata un’eccezione di tipo DOMException. SAX & DOM

  41. Interfaccia Element interface Element { readonly attribute DOMString tagName; DOMString getAttribute(in DOMString name); void setAttribute(in DOMString name, in DOMString value) raises(DOMException); void removeAttribute(in DOMString name) raises(DOMException); Attr getAttributeNode(in DOMString name); Attr setAttributeNode(in Attr newAttr) raises(DOMException); Attr removeAttributeNode(in Attr oldAttr) raises(DOMException); NodeList getElementsByTagName(in DOMString name); void normalize(); }; • Il metodo getElementsByTagName restituisce i soli figli del nodo che siano elementi con uno specifico nome (filtra cioè i childNodes). • Il metodo normalize serve a fondere nodi Text adiacenti nel sottoalbero controllato dall’elemento. SAX & DOM

  42. Interfaccia Attr interface Attr { readonly attribute DOMString name; readonly attribute boolean specified; attribute DOMString value; }; • I valori per name e value sono accessibili anche attraverso i metodi getName e getValue dell’interfaccia Node • L’attributo specified è false se l’attributo non era presente nel documento, ma è stato inserito dal parser con il suo valore di default specificato nel DTD associato al documento stesso. In caso contrario, l’attributo è true SAX & DOM

  43. NodeList e NamedNodeMap interface NodeList { Node item(in unsigned long index); readonly attribute unsigned long length; }; interface NamedNodeMap { Node getNamedItem(in DOMString name); Node setNamedItem(in Node arg, in DOMString value) raises(DOMException); Node removeNamedItem(in DOMString name) raises(DOMException); Node item(in unsigned long index); readonly attribute unsigned long length; }; • Le liste vengono restituite da vari metodi del DOM. • La NamedNodeMap contiene elementi accessibili, oltre che per indice (come in NodeList), anche attraverso il nome (l’attributo nodeName di Node). SAX & DOM

  44. Interfaccia Document interface Document { readonly attribute DocumentType doctype; readonly attribute DOMImplementation implementation; readonly attribute Element documentElement; Element createElement(in DOMString tagName) raises(DOMException); DocumentFragment createDocumentFragment(); Text createTextNode(in DOMString data); Comment createComment(in DOMString data); CDATASection createCDATASection(in DOMString data) raises(DOMException); ProcessingInstruction createProcessingInstruction(in DOMString target, in DOMString data) raises(DOMException); Attr createAttribute(in DOMString name) raises(DOMException); EntityReference createEntityReference(in DOMString name) raises(DOMException); NodeList getElementsByTagName(in DOMString tagname); }; • L’oggetto Document fornisce i metodi per creare i nodi che compongono il documento XML! • documentElement rappresenta l’elemento radice del documento. SAX & DOM

  45. Il DOM con Java: JAXP • JAXP è un’API generica offerta da Java per manipolare il DOM. • In realtà, JAXP è un’interfaccia astratta che deve poggiarsi su una vera implementazione del DOM fornita da terze parti. • E’ possibile usare anche direttamente l’implementazione del DOM. • Noi faremo riferimento al pacchetto Xerces dell’Apache XML Project, di gran lunga il più diffuso e perfezionato. SAX & DOM

  46. DOM con JAXP • JAXP è contenuta nel namespace javax.xml.parsers e javax.xml.transformer import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); } catch (javax.xml.parsers.ParserConfigurationException) { } Document doc = builder.newDocument(); Element root = doc.CreateElement(“HTML”); Element body = doc.CreateElement(“Body”); body.setAttribute(“bgcolor”,”red”); root.appendChild(body); doc.appendChild(root); SAX & DOM

  47. Parsing XML con JAXP • Il controllo offerto dalle interfacce generiche JAXP è minore. import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setNamespaceAware(true); try { DocumentBuilder builder = factory.newDocumentBuilder(); } catch (javax.xml.parsers.ParserConfigurationException) { } try { Document doc = builder.parse(filename); } catch (java.io.IOException ioe) { } catch (org.xml.sax.SAXParseException spe) { } catch (org.xml.sax.SAXException se) { } SAX & DOM

  48. DOM con Xerces • Gli elementi del DOM sono contenuti nel namespace org.w3c.xml • Tutte le interfacce sono implementate esattamente come richiesto dalla specifica sotto forma di interfacce Java. import org.w3c.dom.Document; import org.w3c.dom.Element; import org.apache.xerces.dom.DocumentImpl; … Document doc = new DocumentImpl(); Element root = doc.CreateElement(“HTML”); Element body = doc.CreateElement(“Body”); body.setAttribute(“bgcolor”,”red”); root.appendChild(body); doc.appendChild(root); DocumentImpl è la classe che implementa l’interfaccia Document in xerces (non si può istanziare direttamente Document: è un’interfaccia!) SAX & DOM

  49. Parsing XML con Xerces • Il parser DOM di Xerces è rapresentato dalla classe org.apache.xerces.parsers.DOMParser import org.apache.xerces.parsers.DOMParser; import org.w3c.dom.Document; DOMParser parser = new DOMParser(); try { parser.setFeature("http://xml.org/sax/features/validation", true); } catch (org.xml.sax.SAXNotRecognizedException ex ) { } catch (org.xml.sax.SAXNotSupportedException ex ) { } try { parser.parse(filename); } catch (java.io.IOException ioe) { } catch (org.xml.sax.SAXParseException spe) { } catch (org.xml.sax.SAXException se) { } Document doc = parser.getDocument(); SAX & DOM

  50. Riferimenti • Apache XML Project (xalan, xerces)http://xml.apache.org • Java JAXP Tutorialhttp://java.sun.com/webservices/jaxp/docs.html • SAXhttp://www.saxproject.org/ • Specifiche DOM dal W3Chttp://www.w3.org/DOM/ SAX & DOM

More Related