Simple API for XML (SAX) Ulrich Hoffmann <[email protected]> 1 Simple API für XML (SAX) Ereignisbasierte Verarbeitung von XML Programmiersprachunabhängig: Implementierungen in Java, C++, Python, Perl, Eiffel Java: SAX2 Bestandteil JDK seit 1.4: Java APIs for XML Processing (JAXP) 2 Komponenten einer SAX-Applikation Kontrolle Parser XML-Daten Handler Applikation Files GUI usw. 3 Struktur von SAX ParserFactory Erzeugen unterschiedlicher Parser ausprägungen (validierend/nichtvalidierend, Namespaces) Parser SAX definiert nur abstrake Schnittstellen Implementierungen bieten meist Standardimplementierungen 4 Parser Schnittstellen ContentHandler: Dokumentereignisse startElement, processingInstruction, ... ErrorHandler: Fehlerklassen error, fatalError, warning DTDHandler: Notations, unparsed Entities EntityResolver: Entities 5 SAX-Ausführungsmodell Handler behandeln Ereignisse (Call Backs) Kein durchgängiger Programmfluss geringer Speicherverbrauch (XML > RAM) Push-Modell Keine Änderung des XMLs möglich 6 Struktur eines SAX-Programms Handler-Definitionen durch Implementierung der SAX-Schnittstellen (oder erben aus der Standardimplementierung DefaultHandler) Hauptprogramm: ParserFactory erzeugen (newInstance) ggf. ParserFactory konfigurieren Parser erzeugen (newSaxParser) parse-Methode aufrufen 7 Gerüst für SAX-Programm import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class SAXExample1 extends DefaultHandler { public void startDocument() { System.out.println("document started"); } public void endDocument() { System.out.println("document ended"); } public static void main(String args[]) throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); sp.parse(args[0], new SAXExample1()); } } 8 Die ContentHandler-Schnittstelle Operation startDocument() processingInstruction(String target, String data) startElement(String namespaceURI, String localName, String qName, Attributes atts) characters(char[] ch, int start, int length) ignorableWhitespace(char[] ch, int start, int length) endElement(String namespaceURI, String localName, String qName) startPrefixMapping(String prefix, String uri) endPrefixMapping(String prefix) endDocument() Funktionalität Dokumentenbeginn Verarbeitungsanweisungen Öffnendes Tags Element-Text ignorierbare Leerzeichen Schliessende Tags Gültigkeitsbeginn Präfix Gültigkeitsende Präfix Dokumentenende 9 SAX-Dokumentation Homepage des SAX-Projekts: http://www.saxproject.org/ Java API-Dokumentation: http://java.sun.com/j2se/1.4.2/docs/ api/org/xml/sax/package-summary.html 10 Konfigurieren der ParserFactory Aktivierung der Funktionalität für Namensräume und Validierung SpezialMethoden am ParserFactoryObjekt: setNameSpaceAware(bool); setValidating(bool); Generele Methode am ParserFactoryObjekt: setFeature(string, bool); 11 Fehlerbehandlung Für Fehler während der XML-Bearbeitung mit SAX werden SAXExceptions ausgelöst: SaxNotRecognizedException Initialisierung, falsche Parametrierung SaxParseException während des Parsens - Wohlgeformtheit SaxNotSupportedException Parametrierung richtig aber nicht unterstützt 12 SaxParseException Exceptionobjekt hat Methoden um die Fehlerstelle zu lokalisieren: getColumnNumber getLineNumber getSystemID / getPublicID 13 Fehlerbehandlungsbeispiel import import import import org.xml.sax.SAXParseException; org.xml.sax.helpers.DefaultHandler; javax.xml.parsers.SAXParser; javax.xml.parsers.SAXParserFactory; public class SAXExample2 extends DefaultHandler { public static void main(String args[]) throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); try { sp.parse(args[0], new SAXExample2()); } catch (SAXParseException spe) { System.out.println("A SAXParseException occured ...\n" + "at column " + spe.getColumnNumber() + "\n" + "at line " + spe.getLineNumber() + "\n" + "public identifier of document is: " + spe.getPublicId() + "\n" + "system identifier of document is: " + spe.getSystemId()); } } } 14