XML - SSW

Werbung
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
Herunterladen