XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API-Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 1 JAXP - XML-Verarbeitung in Java JAXP – Java API for XML Processing (http://java.sun.com/xml/jaxp/index.jsp) • unterstützt Parsen und Transformation von XML-Dokumenten JAXP enthält • Standard-APIs zur XML-Verarbeitung org.w3c.dom org.xml.sax java.xml.stream • Implementierungen Client javax.xml.parsers • Plugability: Bindung der Implementierungen an APIs über Factory-Pattern Î Implementierung bleibt verborgen Î Implementierung kann ausgetauscht werden! API Implementations PlugabilityLayer JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 2 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 3 XML-Dokumente XML-Dokumente bestehen aus • Deklarationen • Baum von Elementen jedes Element hat • Namen • Inhalt • Attribute jedes Element kann eindeutige ID haben • Attribut id • Wert muss eindeutig im Dokument sein Struktur der Elemente < element_name attributes > content </ element_name > <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE addressbook SYSTEM "addressbook.dtd"> <addressbook owner="p1" date="2005-03-12"> <person id="p1"> <firstname>Thomas</firstname> <lastname>Kotzmann</lastname> <email>[email protected]</email> </person> <company id="c1"> <companyname>Sun</companyname> <url>www.sun.com</url> </company> <person id="p2"> <firstname>Markus</firstname> <lastname>Loeberbauer</lastname> <email>[email protected]</email> </person> <person id="p3"> <firstname>Herbert</firstname> <lastname>Praehofer</lastname> <email type="home">[email protected]</email> </person> </addressbook> JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 4 Hierarchie und Navigation Wurzelelement (root) addressbook-Element Kinder (children) person-Elemente sind Kinder von addressbook firstname, lastname und emailElemente sind Kinder von person Vater (parent) person-Elemente sind Väter der firstname, lastname und emailElemente Geschwister (siblings) firstname und lastname-Elemente sind Geschwister von email-Element Vorgänger (ancestors) alle Väter und deren Väter Nachfolger (descendents) <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE addressbook SYSTEM "addressbook.dtd"> <addressbook owner="p1" date="2005-03-12"> <person id="p1"> <firstname>Thomas</firstname> <lastname>Kotzmann</lastname> <email>[email protected]</email> </person> <company id="c1"> <companyname>Sun</companyname> <url>www.sun.com</url> </company> <person id="p2"> <firstname>Markus</firstname> <lastname>Loeberbauer</lastname> <email>[email protected]</email> </person> <person id="p3"> <firstname>Herbert</firstname> <lastname>Praehofer</lastname> <email type="home">[email protected]</email> </person> </addressbook> Alle Kinder und deren Kinder JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 5 Deklarationen XML-Deklaration: <?xml version encoding standalone ?> • version: Version von XML • encoding: verwendete Zeichenkodierung • standalone: "yes" = ohne Verweis, "no" = mit Verweis auf andere Dokumente <?xml version="1.0" encoding="utf-8" standalone="no" ?> Deklaration des verwendeten Schemas (DTD) • Name des Wurzelelements • verwendetes Schema z.B. URL der verwendeten DTD-Datei <!DOCTYPE addressbook SYSTEM "addressbook.dtd"> JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 6 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 7 Schemadefinition Definition der erlaubten Elemente und der Struktur des Dokuments XML-Dokumente können gegen Schema validiert werden 2 Arten: • XML Schema: Schema eines XML-Dokuments in XML • DTDs: älteres Format DTD besteht aus • Deklaration der Elemente: !ELEMENT <!ELEMENT element_name (content_model)> • Deklaration der Attribute für die Elemente: !ATTLIST <!ATTLIST target_elem attr_name attr_type default …> JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 8 Beispiel DTD <!ELEMENT addressbook ((person | company)*)> <!ATTLIST addressbook owner IDREF #REQUIRED date CDATA #IMPLIED> <!ELEMENT person (firstname, lastname, email)> <!ATTLIST person id ID #REQUIRED> <!ELEMENT firstname (#PCDATA)> addressbook.dtd <!ELEMENT lastname (#PCDATA)> <!ELEMENT email (#PCDATA)> <!ATTLIST email type (home | business) "business"> <!ELEMENT company (companyname, url)> <!ATTLIST company id ID #REQUIRED> <!ELEMENT companyname (#PCDATA)> <!ELEMENT url (#PCDATA)> <?xml version="1.0" encoding="utf-8"?> addressbook.xml <!DOCTYPE addressbook SYSTEM "addressbook.dtd"> <addressbook owner="p1" date="2005-03-12"> <person id="p1"> <firstname>Thomas</firstname> <lastname>Kotzmann</lastname> <email>[email protected]</email> </person> <company id="c1"> <companyname>Sun</companyname> <url>www.sun.com</url> … </addressbook> JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 13 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 14 Parsen von XML-Dokumenten 3 Arten von Parser: DOM: Document Object Model • Hauptspeicherrepräsentation des XML-Dokuments wird erstellt • API: org.w3c.dom • Implementierung: javax.xml.parsers SAX: Simple API for XML • Ereignisse beim Lesen zeigen Inhalte an • API: org.xml.sax • Implementierung: javax.xml.parsers StAX: Streaming API for XML • Durchlaufen von XML • API/Implementierung: javax.xml.stream JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 15 DOM Hauptspeicherrepräsentation des Inhalts einer XML-Datei Knotenstruktur (DOM-Baum) objektorientierter Zugriff Interfaces: (aus org.w3c.dom) Document DocumentType Node Element Text Attr CharacterData EntityReference CDATASection Comment Entity … JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 16 Beispiel DOM-Baum <?xml version="1.0" encoding="utf-8"?> Document DocumentType <!DOCTYPE addressbook SYSTEM "addressbook.dtd"> … Element: addressbook <addressbook Attr: owner = "p1“ owner="p1" Attr: date = "2005-03-12“ date="2005-03-12"> Element: person <person Attr: id = "p1“ id="p1"> Element: fistname <firstname> Thomas </firstname> Text: Thomas <lastname> Element: lastname Kotzmann </lastname> Text: Kotzmann … … JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 17 DocumentBuilder: Parsen eines XML-Dokuments Parsen erfolgt mittels DocumentBuilder DocumentBuilder wird durch DocumentBuilderFactory erzeugt DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setIgnoringElementContentWhitespace(true); try { DocumentBuilder builder = factory.newDocumentBuilder(); File file = new File("addressbook.xml"); Document doc = builder.parse(file); ... repräsentiert XML-Dokument } catch (ParserConfigurationException e) { … } catch (SAXException e) { … } catch (IOException e) { … } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 18 Navigieren im DOM-Baum (1) Zugriff auf DOM-Baum vom Document-Knoten ausgehend • getDocumentElement liefert Wurzelelement Element addressbook = doc.getDocumentElement(); System.out.print(addressbook.getNodeName()); Attribute eines Knotens mit getAttributes NamedNodeMap attrs = addressbook.getAttributes(); Attr owner = (Attr) attrs.getNamedItem("owner"); Attr date = (Attr) attrs.getNamedItem("date"); Zugriff auf Unterknoten mit getChildNodes und auf Attribute mit getAttribute NodeList entries = addressbook.getChildNodes(); for (int i = 0; i < entries.getLength(); i++) { Element entry = (Element)entries.item(i); if (entry.getNodeName().equals("person")) { String id = entry.getAttribute("id"); JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 19 Navigieren im DOM-Baum (2) Zugriff auf bestimmte Unterknoten mit getElementsByTagName NodeList fnNodeList= entry.getElementsByTagName("firstname"); Zugriff auf Listenelemente und Unterelemente Element fnElem = (Element) fnNodeList.item(0); Text fnText = (Text) fnElem.getFirstChild(); String fnString = fnText.getNodeValue(); Direktzugriff auf Elemente mit eindeutiger ID (Methode getElementById von Document) Element getElementById(String id) Element owner = doc.getElementById(doc.getDocumentElement().getAttribute("owner")) ; JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 20 Beispiel: Ausgabe von addressbook.xml (1) DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); addressbook: owner = p1, date = .. factory.setIgnoringElementContentWhitespace(true); person: id = p1 Name: Thomas Kotzmann try { Email: [email protected] DocumentBuilder builder = company: id = c1 factory.newDocumentBuilder(); Name: Sun File file = new File("addressbook.xml"); URL: www.sun.com person: id = p2 Document doc = builder.parse(file); Name: Markus Loeberbauer // root element Email: [email protected] Element addressbook = doc.getDocumentElement(); person: id = p3 // attributes of address book Attr owner = addressbook.getAttributeNode("owner"); Name: Herbert Praehofer Email: [email protected] String date = addressbook.getAttribute("date"); System.out.println("" + addressbook.getNodeName() + ": " + owner.getNodeName() + " = " + owner.getValue() + ", date = " + date); // subelements person | company NodeList entries = addressbook.getChildNodes(); for (int i = 0; i < entries.getLength(); i++) { Element entry = (Element)entries.item(i); // id attribute String id = entry.getAttribute("id"); System.out.println(" " + entry.getNodeName() + ": id = " + id); ... JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 21 Beispiel: Ausgabe von addressbook.xml (2) if (entry.getNodeName().equals("person")) { // first Name NodeList fnNodeList = entry.getElementsByTagName("firstname"); Element fnElem = (Element)fnNodeList.item(0); Text fnText = (Text)fnElem.getFirstChild(); String fnString = fnText.getNodeValue(); // lastName NodeList lnNodeList = entry.getElementsByTagName("lastname"); Element lnElem = (Element)lnNodeList.item(0); Text lnText = (Text)lnElem.getFirstChild(); String lnString = lnText.getNodeValue(); // emails NodeList emailNodeList = entry.getElementsByTagName("email"); Element emailElem = (Element)emailNodeList.item(0); Text emailText = (Text)emailElem.getFirstChild(); String emailString = emailText.getNodeValue(); System.out.println(" Name: " + fnString + " " + lnString); System.out.println(" Email: " + emailString); } else if (entry.getNodeName().equals("company")) } Node cnNode = entry.getElementsByTagName("companyname").item(0); Node urlNode = entry.getElementsByTagName("url").item(0); System.out.println(" Name: " + cnNode.getFirstChild().getNodeValue()); System.out.println(" URL: " + urlNode.getFirstChild().getNodeValue()); } } // end for } catch (ParserConfigurationException e) { … } catch (SAXException e) { … } KEPLER catch (IOException e) { … } JOHANNES UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 22 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 23 SAX-Parser SAX-Parser liest XML-Dokument und generiert Ereignisse • Anfang und Ende von Dokument, • Anfang und Ende von Elementen, • Auftreten von Textknoten, etc. Ereignisbehandlung in ContentHandler (implementiert von DefaultHandler) public interface ContentHandler { void startDocument() throws SAXException void endDocument() throws SAXException void startElement( String namespaceURI, String localName, String qName, Attributes atts) throws SAXException void endElement( String namespaceURI, String localName, String qName, Attributes atts) throws SAXException void characters(char[] ch, int start, int length) throws SAXException ... public class DefaultHandler implements ContentHandler, EntityResolver, DTDHandler, ErrorHandler JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 24 Vorgehen SAXParserFactory erzeugen SAXParser erzeugen parse mit Datei und Handler-Objekt aufrufen SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); try { SAXParser saxParser = factory.newSAXParser(); // parse … Handler-Objekt File file = new File("addressbook.xml"); saxParser.parse(file, new PrintElementsHandler()); } catch (ParserConfigurationException e1) { … } catch (SAXException e1) { … } catch (IOException e) { … } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 25 Handler Im Handler auf die Ereignisse reagieren und Inhalt auswerten class PrintElementsHandler extends DefaultHandler { public void startDocument() throws SAXException { // Anfang von Dokument behandeln } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // Element behandeln } public void characters(char[] ch, int start, int length) throws SAXException { // Textknoten behandeln } public void endElement(String uri, String localName, String qName) throws SAXException { // Ende von Element behandeln } public void endDocument() throws SAXException { // Ende von Dokument behandeln } } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 26 Beispiel: Ausgabe von addressbook.xml (1) Ausgabe der Elemente, Attribute und Textknoten mit Einrückung und Tiefe des Knotens import import import import java.io.*; javax.xml.parsers.*; org.xml.sax.*; org.xml.sax.helpers.DefaultHandler; public class SAXParserTest { public static void main(String[] args) { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); SAXParser saxParser; try { saxParser = factory.newSAXParser(); // parse … File file = new File("addressbook.xml"); saxParser.parse(file, new PrintElementsHandler()); } catch (ParserConfigurationException e1) { } catch (SAXException e1) { } catch (IOException e) { } } } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 27 Beispiel: Ausgabe von addressbook.xml (2) class PrintElementsHandler extends DefaultHandler { StringBuffer blanks = new StringBuffer(); // leading blanks int depth = 0; // depth of node public void startDocument() throws SAXException { System.out.println("start document -----------------------------"); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { blanks.append(" "); // add 3 blanks depth++; // increase depth System.out.print(blanks.toString() + depth + " - " + qName + ": "); for (int i = 0; i < attributes.getLength(); i++) { System.out.print(attributes.getQName(i) + " = " + attributes.getValue(i) + " "); } System.out.println(); } public void characters(char[] ch, int start, int length) throws SAXException { String s = new String(ch, start, length); System.out.println(blanks.toString() + " " + (depth+1) + } ... " - " + s); JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 28 Beispiel: Ausgabe von addressbook.xml (3) public void endElement(String uri, String localName, String qName) throws SAXException { blanks.delete(0, 3); // delete 3 blanks depth--; // decrease depth } public void endDocument() throws SAXException { System.out.println("end document ------------------------------"); } } start document ---------------------------1 - addressbook: owner = p1 date = 2005-03-12 2 - person: id = p1 3 - firstname: 4 - Thomas 3 - lastname: 4 - Kotzmann 3 - email: type = business 4 - [email protected] 2 - company: id = c1 3 - companyname: 4 - Sun 3 - url: 4 - www.sun.com 2 - person: id = p2 ... end document ------------------------------ JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 29 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 30 StAX-Reader (Java 6.0) XML-Dokument lesen mit StAX • Verarbeitung erfolgt on the fly • Nur von vorne nach hinten • Programmgetrieben Vorgehen • Erstellen einer XMLInputFactory • XMLStreamReader erzeugen • Durchlaufen des XML-Dokuments Beispiel • MovieDB, einlesen von Filmen und Schauspielern JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 31 StAX Beispiel MovieDB lesen 1/2 List<Movie> readMovies() { List<Movie> movies = new ArrayList<Movie>(); FileInputStream movieFile = null; try { movieFile = new FileInputStream("movies.xml"); XMLInputFactory xmlInFact = XMLInputFactory.newInstance(); XMLStreamReader movieReader = xmlInFact.createXMLStreamReader(movieFile); readMovies(movieReader, movies); } catch (IOException exc) { // ... log ... } catch (XMLStreamException exc) { // ... log ... } finally { if (movieFile != null) { try { movieFile.close(); } catch (IOException exc) { // ... log ... } } } return movies; } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 32 StAX Beispiel MovieDB lesen 2/2 void readMovies(XMLStreamReader movieReader, List<Movie> movies) throws XMLStreamException { Movie m = null; while (movieReader.hasNext()) { movieReader.next(); if (movieReader.getEventType() != XMLStreamReader.START_ELEMENT) { continue; } NamespaceURI if (Movie.ID.equals(movieReader.getLocalName())) { m = new Movie(); m.name = movieReader.getAttributeValue(null, Movie.NAME_PROP); movies.add(m); } Lokaler Name else if (Actor.ID.equals(movieReader.getLocalName())) { Actor a = new Actor(); a.name = movieReader.getAttributeValue(null, Actor.NAME_PROP); m.actors.add(a); } class Movie { } public static final String ID = "movie"; } public static final String NAME_PROP = "name"; public String name; public List<Actor> actors = new ArrayList<Actor>(); } class Actor { public static final String ID = "actor"; public static final String NAME_PROP = "name"; public String name; } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 33 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 34 Erzeugen von XML-Dokumenten XML-Dokumente werden erzeugt durch • Aufbauen eines DOM-Baums • Schreiben über XSL-Transformation Vorgehen beim Aufbau eines DOM-Baums • Erzeugen eines neuen Document-Objekts mittels DocumentBuilder Document doc = builder.newDocument(); • Erzeugen neuer Elemente für Document-Objekt Element root = doc.createElement("addressbook"); Element person1 = doc.createElement("person"); • Anfügen der Elemente bei Vaterknoten doc.appendChild(root); root.appendChild(person1); • Anfügen von Attributen bei Elementen root.setAttribute("date", "2005-03-22"); person1.setAttribute("id", "p1"); JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 35 Erzeugen von XML-Dokumenten (2) Schreiben des DOM-Baums mittels XSL-Transformation • Quelle DOM-Baum in Ziel Datei transformieren (Achtung: es erfolgt keine wirkliche Datentransformation) Vorgehen beim Schreiben über XSL-Transformation • Erzeugen eines Transformers TransformerFactory fact = TransformerFactory.newInstance(); Transformer t = fact.newTransformer(); • • Ausgabeeigenschaften setzen (für DOCTYPE und Leerzeilen) t.setOutputProperty("doctype-system", "addressbook.dtd"); t.setOutputProperty("indent", "yes"); Transformation mit Dokument als Quelle und FileOutputStream als Ziel anwenden t.transform( new DOMSource(doc), // source new StreamResult(new FileOutputStream(file)) // target ); JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 37 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 39 StAX-Writer XML-Dokument schreiben mit StAX • Im Gegensatz zu SAX kann man mit StAX auch schreiben • Schreiben erfolgt wie das lesen on the fly • Nur von vorne nach hinten • Programmgetrieben Vorgehen • Erstellen einer XMLOutputFactory • XMLStreamWriter erstellen • Schreiben des XML-Dokuments Beispiel • MovieDB schreiben von Filmen und Schauspielern JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 40 StAX Beispiel MovieDB schreiben 1/2 void writeMovies(List<Movie> movies) { FileOutputStream movieFile = null; try { movieFile = new FileOutputStream("movies.xml"); XMLOutputFactory xmlOutFact = XMLOutputFactory.newInstance(); XMLStreamWriter movieWriter = xmlOutFact.createXMLStreamWriter(movieFile); writeMovies(movieWriter, movies); } catch (IOException exc) { // ... log ... } catch (XMLStreamException exc) { // ... log ... } finally { if (movieFile != null) { try { movieFile.close(); } catch (IOException exc) { // ... log ... } } } } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 41 StAX Beispiel MovieDB schreiben 2/2 void writeMovies(XMLStreamWriter movieWriter, List<Movie> movies) throws XMLStreamException { movieWriter.writeStartDocument(); movieWriter.writeStartElement("movielist"); Lokaler Name for (Movie m : movies) { movieWriter.writeStartElement(Movie.ID); movieWriter.writeAttribute(Movie.NAME_PROP, m.name); for (Actor a : m.actors) { Wert movieWriter.writeEmptyElement(Actor.ID); movieWriter.writeAttribute(Actor.NAME_PROP, a.name); } movieWriter.writeEndElement(); } movieWriter.writeEndElement(); movieWriter.flush(); } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 42 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOMaus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 43 XML-Transformation mit XSLT XSLT ermöglicht die Transformation von XML-Dokumenten XSL-Stylesheet ist ein Dokument mit einer Menge von Transformationsregeln Regeln (templates) beschreiben die Transformation von XML-Elementen • XPath-Ausdrücke definieren die Prämissen der Regeln (match) • im Rumpf der Regel wird die Generierung des transformierten Elements beschrieben <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match=xpath-expression> construction of transformed elements </xsl:template> </xsl:stylesheet> JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 44 XSL-Transformation Source: das zu transformierende XML-Dokument Result: Zieldaten in beliebigem Format (z.B. HTML) StyleSheet: XSL-Dokument mit Transformationsregeln StyleSheet: XSL-Dokument Source: XMLDokument Transformation Result: Dokument JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 45 XPath XPath ist ein Adressierungsmechanismus für Elemente in XML-Dokumenten XPath-Ausdruck (Location path) selektiert eine Menge von Knoten Ein Location path besteht aus Location steps, die mit "/" getrennt sind Location steps können definieren • Elementnamen: element_name • Attribute: @attribute • Bedingungen: [condition] • Positionen: [index] Beispiele von Location paths: "*" Selektiert alle Knoten "/" Wurzelknoten "/addressbook/*" Selektiert alle Elemente unter einen addressbook-Element "/addressbook/person[1]" Liefert die ersten person-Elemente von addressbookElementen "/addressbook/*/firstname" Liefert alle firstname-Element unter den addressbookElementen "/addressbook/person[@id="p1"]" Liefert den Personenknoten mit id = “p1” "/*/email[@type="home"]" Liefert alle email-Knoten die von Typ “home” sind JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 46 Beispiel XSL-Stylesheet <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>XML Address Book</title> </head> <body> <table border="3" cellspacing="10" cellpadding="5"> <xsl:apply-templates/> </table> </body> </html> </xsl:template> <xsl:template match="addressbook"> <xsl:apply-templates select="person"/> </xsl:template> <xsl:template match="person"> <tr> <td> <xsl:value-of select="firstname"/> </td> <td> <b><xsl:value-of select="lastname"/></b> </td> <td> <xsl:value-of select="email"/> </td> </tr> </xsl:template> </xsl:stylesheet> JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 47 Beispiel Transformation ursprüngliches XML-Dokument <?xml version='1.0' encoding="utf-8"?> <addressbook owner="1"> erzeugtes HTML-Dokument <person id="1"> <firstname>Thomas</firstname> <html> <lastname>Kotzmann</lastname> <head> <email>[email protected]</email> <META http-equiv="Content-Type" </person> content="text/html; charset=utf-8"> <person id="2"> <title>XML-AddressBook</title> <firstname>Markus</firstname> </head> <lastname>Loeberbauer</lastname> <body> <email>[email protected]</email> <table border="3" cellspacing="10" cellpadding="5"> </person> <tr> </addressbook> <td>Thomas</td> <td><b>Kotzmann</b></td> <td>[email protected]</td> </tr> <tr> <td>Markus</td> <td><b>Loeberbauer</b></td> <td>[email protected]</td> </tr> </table> </body> </html> JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 48 XSL-Transformation in JAXP Package javax.xml.transform Transformer und TransformerFactory Abstraktion von Quellen (inkl StyleSheets) und Senken • Source Interfaces - Source StreamSource - Result • SAXSource Implementierungen DOMSource - DOMSource, SAXSource, StreamSource - DOMResult, SAXResult, StreamResult Result StreamResult SAXResult DOMResult JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 49 Vorgehen Source für StyleSheet und Transformer erzeugen TransformerFactory facty = TransformerFactory.newInstance(); File styleSheetFile = new File("addressbook.xsl"); StreamSource styleSheet = new StreamSource(styleSheetFile); Transformer t = facty.newTransformer(styleSheet); Source für Quelldokument erzeugen Transformer mit Style sheet File inFile = new File("addressbook.xml"); Document doc = builder.parse(inFile); DOMSource source = new DOMSource(doc); Result für Ergebnis erzeugen File outFile = new File("addressbook.html"); StreamResult result = new StreamResult( new FileOutputStream( outFile)); Transformation durchführen t.transform(source, result); JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 50 Beispiel: Transformation XML - HTML try { ... // create transformer with style sheet TransformerFactory fact = TransformerFactory.newInstance(); File styleSheetFile = new File("addressbook.xsl"); StreamSource styleSheet = new StreamSource(styleSheetFile); Transformer t = fact.newTransformer(styleSheet); // create source File inFile = new File("addressbook.xml"); Document doc = builder.parse(inFile); DOMSource source = new DOMSource(doc); // create target File outFile = new File("addressbook.html"); StreamResult result = new StreamResult(new FileOutputStream(outFile)); // transform t.transform(source, result); } catch (TransformerException e) { … } } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 51 XML XML-Dokumente Schemadefinition DOM-Parser SAX-Parser StAX-Reader Erzeugen von XML-Dokumenten aus DOM Schreiben von XML-Dokumenten mit StAX XSL-Transformation Java Architecture for XML Binding API – Auszug JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 52 Java Architecture for XML Binding (JAXB 2.0) Bindet Objektzustände an XML-Dokumente • Abbildung durch Annotationen festlegbar • Automatisches Serialisieren ganzer Objektbäume Vorgehen • Annotieren der Klassen, Felder, Properties • JAXBContext anlegen, bekanntgeben der betroffenen Klassen • Lesen mit einem Unmarshaller • Schreiben mit einem Marshaller Beispiel • MovieDB JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 53 Beispiel MovieDB annotieren (JAXB 2.0) @XmlRootElement(name="movielist") class MovieList implements Iterable<Movie> { public List<Movie> movies = new ArrayList<Movie>(); public void add(Movie m) { movies.add(m); } public Iterator<Movie> iterator() { return movies.iterator(); } } @XmlRootElement(name="movie") class Movie { @XmlAttribute public String name; @XmlElement(name="actor-list") public List<Actor> actors = new ArrayList<Actor>(); } @XmlRootElement class Actor { @XmlElement(name="actor-name") public String name; } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 54 Beispiel MovieDB lesen (JAXB 2.0) MovieList readMovies() { MovieList movies = new MovieList(); FileInputStream movieFile = null; try { movieFile = new FileInputStream("movies.xml"); JAXBContext ctx = JAXBContext.newInstance(MovieList.class); Unmarshaller um = ctx.createUnmarshaller(); movies = (MovieList) um.unmarshal(movieFile); Betroffene Klassen } catch (IOException exc) { (referenzierte zur // ... log ... Compilezeit bekannte } catch (JAXBException exc) { // ... log ... Klassen werden } finally { selbstständig erkannt) if (movieFile != null) { try { movieFile.close(); } catch (IOException exc) { // ... log ... } } } return movies; } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 55 Beispiel MovieDB schreiben (JAXB 2.0) void writeMovies(MovieList movies) { FileOutputStream movieFile = null; try { movieFile = new FileOutputStream("movies.xml"); JAXBContext ctx = JAXBContext.newInstance(MovieList.class); Marshaller ma = ctx.createMarshaller(); ma.marshal(movies, movieFile); } catch (IOException exc) { // ... log ... } catch (JAXBException exc) { // ... log ... } finally { if (movieFile != null) { try { movieFile.close(); } catch (IOException exc) { // ... log ... } } } } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 56 JAXB 2.0 – API, wichtige Annotationen Namespaces • javax.xml.bind • javax.xml.bind.annotation Annotationen: • @XmlRootElement - Klassen, Enums - Abbildung auf XML Elemente • @XmlElement - Properties, Felder - Abbildung auf XML Elemente • @XmlAttribute - Properties, Felder - Abbilding auf XML Attribute JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 57 Zusammenfassung SAX, StAX, DOM oder JAXB? SAX StAX DOM JAXB Lesen Ja Ja Ja Ja Schreiben Nein Ja Ja Ja Ändern Nein Nein Ja - Speicherbedarf Einfachheit Niedrig Komplex Niedrig Einfach Hoch Einfach Einfach bis Komplex JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 58