XML-Parser

Werbung
XML-Parser
© K. Schild, 2006 / M. Mochol 2007
1
Heutige Vorlesung
letzte Woche
;
XML-Schema
- Datentypen
- Element- und Attribut-Deklarationen
- Typsubstitution
heutige Vorlesung
ƒ Welche XML-Parser gibt es?
ƒ Was sind ihre Vor- und Nachteile?
ƒ Schema-Übersetzer als Alternative
© K. Schild, 2006 / M. Mochol 2007
2
Grundlegende Architektur
Zeichenkette
XMLDokument
Anwendung
Serialisierer
Parser
standardisierte
APIs
Parser
ƒ analysiert XML-Dokument und erstellt evtl. Parse-Baum mit
Tags, Text-Inhalten und Attribut-Wert-Paaren als Knoten
Serialisierer
ƒ Datenstruktur Î XML-Dokument
© K. Schild, 2006 / M. Mochol 2007
3
Kategorien von Parser
Validierender vs. nicht-validierender Parser
ƒ Wird die Validität des Dokumentes untersucht?
Pull- vs. Push-Parser
ƒ Wer hat Kontrolle über das Parsen: die Anwendung oder
der Parser?
Einschritt- vs. Mehrschritt-Parser
ƒ Wird das XML-Dokument in einem Schritt vollständig
geparst oder Schritt für Schritt?
ƒ Beachte: Kategorien unabhängig voneinander, können
kombiniert werden
© K. Schild, 2006 / M. Mochol 2007
4
Validierender vs. nicht-validierender
Validierender Parser
ƒ Ist das XML-Dokument valide?
ƒ DTD oder XML-Schema erforderlich
ƒ Ist das XML-Dokument wohlgeformt?
Nicht-validierender Parser
ƒ Ist das XML-Dokument wohlgeformt?
© K. Schild, 2006 / M. Mochol 2007
5
Pull-Parser
nächste Einheit?
geparste Einheit
Pull-Parser
nächste Einheit?
Anwendung
geparste Einheit
ƒ Anwendung hat Kontrolle über das Parsen.
ƒ Analyse der nächsten syntaktischen Einheit muss aktiv
angefordert werden.
ƒ Beachte: „Pull” aus Perspektive der Anwendung.
© K. Schild, 2006 / M. Mochol 2007
6
Push-Parser
alles Parsen!
geparste Einheit
Push-Parser
geparste Einheit
Anwendung
geparste Einheit
ƒ Parser hat Kontrolle über das Parsen.
ƒ Sobald der Parser eine syntaktische Einheit analysiert
hat, übergibt er die entsprechende Analyse.
ƒ Beachte: „Push” aus Perspektive der Anwendung.
© K. Schild, 2006 / M. Mochol 2007
7
XML-Parser
One step
Pull
Multi step
JAXP
DOM
ƒ JAXP:
JAXP Java API for XML
Processing
Push
SAX
ƒ JAXP in J2SE 5.0 & Java
WSDP 2.0 enthalten
ƒ DOM:
DOM Document Object Model
ƒ SAX:
SAX Simple API for XML
© K. Schild, 2006 / M. Mochol 2007
8
SAX-Parser
© K. Schild, 2006 / M. Mochol 2007
9
SAX: Simple API for XML
ƒ Mehrschritt-Push-Parser für XML
ƒ kein W3C-Standard, sondern de facto Standard
ƒ standardisiertes API
ƒ ursprünglich nur Java-API
ƒ inzwischen werden aber auch viele andere Sprachen
unterstützt: C, C++, VB, Pascal, Perl
ƒ http://www.saxproject.org/
ƒ auch in MSXML integriert
© K. Schild, 2006 / M. Mochol 2007
10
Ereignisbasiertes Parsen
SAX-Parser
Ereignis: neue
syntaktische Einheit
geparst
einmaliges
Anstoßen des
Parsers
Event Handler
Anwendung
© K. Schild, 2006 / M. Mochol 2007
11
Beispiel
<priceList>
<coffee>
<name>
Mocha Java
</name>
<price>
11.95
</price>
</coffee>
</priceList>
Parser ruft startElement(…,priceList,…) auf.
Parser ruft startElement(…,coffee,…) auf.
Parser ruft startElement(…,name,…) auf.
Parser ruft characters("Mocha Java",…) auf.
Parser ruft endElement(…,name,..) auf.
Parser ruft startElement(…,price,…) auf.
Parser ruft characters("11.95",…) auf.
Parser ruft endElement(…,price,…) auf.
Parser ruft endElement(…,coffee,…) auf.
Parser ruft endElement(…,priceList,…) auf.
ƒ Ereignisfluss:
Ereignisfluss Sobald Einheit geparst wurde, wird
Anwendung benachrichtigt.
ƒ Beachte: Es wird kein Parse-Baum aufgebaut!
© K. Schild, 2006 / M. Mochol 2007
12
Callback-Methoden
ƒ Methoden des Event-Handlers (also der Anwendung),
die vom Parser aufgerufen werden
ƒ für jede syntaktische Einheit eigene Callback-Methode,
u.a.:
- startDocument und endDocument
- startElement und endElement
- characters
- processingInstruction
DefaultHandler
ƒ Standard-Implementierung der Callback-Methoden: tun
jeweils nichts!
ƒ können natürlich überschrieben werden
© K. Schild, 2006 / M. Mochol 2007
13
Interface ContentHandler
ƒ startDocument – einmalig zu Beginn des Parsens
ƒ endDocument – einmalig am Ende des Parsens aufgerufen
ƒ startPrefixMapping – wenn eine Präfixbindung für einen
Namensraum beginnt
ƒ endPrefixMapping – wenn eine Präfixbindung für einen
Namensraum endet
ƒ startElement – wenn ein Starttag geparst wurde
ƒ endElement – wenn ein Endtag geparst wurde
ƒ characters – wenn beim Parsen des Elementinhalts
Zeichendaten (#PCDATA) angetroffen werden
© K. Schild, 2006 / M. Mochol 2007
14
Callback-Methode startElement
public void startElement(java.lang.String
uri,
startElement
java.lang.String localName,
java.lang.String qName,
Attributes attributes)
throws SAXException
uri:
uri Namensraum-Bezeichner oder leerer String
localName:
localName lokaler Name ohne Präfix oder leerer String
qName:
qName Name mit Präfix oder leerer String
attributes:
attributes zu dem Element gehörige Attribute
Attribute können über ihre Position (Index) oder ihren
Namen zugegriffen werden
ƒ endElement ähnlich, jedoch ohne attributes
ƒ
ƒ
ƒ
ƒ
ƒ
© K. Schild, 2006 / M. Mochol 2007
15
Callback-Methode characters
public void characters(char[]
buffer,
characters
int offset,
int length)
throws SAXException
buffer: Liste von Zeichen
offset: Anfangsindex
offset+length
String s = new String(buffer, offset, length);
© K. Schild, 2006 / M. Mochol 2007
16
Beispiel
<priceList>
<coffee>
<name>
Mocha Java
</name>
<price>
11.95
</price>
</coffee>
</priceList>
© K. Schild, 2006 / M. Mochol 2007
ƒ Aufgabe: Gib den Preis von
Mocha Java aus!
ƒ Hierfür benötigen wir zwei
Dinge:
1. einen SAX-Parser
2. passende CallbackMethoden
17
Wie bekomme ich einen SAX-Parser?
SAXParserFactory factory = SAXParserFactory.newInstance();
ƒ liefert eine SAXParserFactory
SAXParser saxParser = factory.newSAXParser();
ƒ liefert einen SAXParser
saxParser.parse("priceList.xml", handler);
ƒ stößt SAX-Parser an
ƒ priceList.xml: zu parsende Datei, kann auch URL oder
Stream sein
ƒ handler: Instanz von DefaultHandler, implementiert
Callback-Funktionen
© K. Schild, 2006 / M. Mochol 2007
18
Exkurs: Factory Method
ƒ Entwurfsmuster aus „Design Patterns“ von Gamma,
Helm, Johnson, Vlissides (1995)
ƒ liefert ein Objekt
ƒ Objekt ist Instanz einer abstrakten Klasse oder einem
Interface.
ƒ abstrakte Klasse / Interface von mehreren Klassen
implementiert
ƒ Beispiel: Iterator i = list.iterator();
ƒ Beispiel: SAXParser saxParser = factory.newSAXParser();
© K. Schild, 2006 / M. Mochol 2007
19
Logik der Callback-Methoden
<priceList>
<coffee>
<name>
Mocha Java
</name>
<price>
11.95
</price>
</coffee>
</priceList>
ƒ Zustände als
boolesche
Variablen
© K. Schild, 2006 / M. Mochol 2007
Start
inName
startElement =
"name"?
characters = "Mocha Java"?
inMochaJava
startElement = "price"?
inMJPrice
characters = "s"?
print(s)
20
Die Callback-Methoden in Java
public void startElement(..., String elementName, ...) {
if (elementName.equals("name")){ inName = true; }
else if (elementName.equals("price") && inMochaJava ){
inMJPrice = true;
inMochaJava = false; } }
public void characters(char [] buf, int offset, int len) {
String s = new String(buf, offset, len);
if (inName && s.equals("Mocha Java")) {
inMochaJava = true;
inName = false; }
else if (inMJPrice) {
System.out.println("The price of Mocha Java is: " + s);
inMJPrice = false; } }
ƒ alle anderen Callback-Methoden
aus DefaultHandler = tun nichts
© K. Schild, 2006 / M. Mochol 2007
21
Start: Auf <name> warten
public void startElement(...,
String elementName, ...){
startElement
if (elementName.equals("name")){ inName = true; }
else if (elementName.equals("price") && inMochaJava ){
inMJPrice = true;
<name>Mocha
Java</name>
name>
inMochaJava = false; } }
<price>11.95</price>
public void characters(char [] buf, int offset, int len) {
String s = new String(buf, offset, len);
if (inName && s.equals("Mocha Java")) {
inMochaJava = true;
inName = false; }
Start
else if (inMJPrice) {
ƒ Anfangszustand
System.out.println("The
price of Mocha Java is: " + s);
inMJPrice = false;
} } eigene Zustandsvariable
ƒ keine
Start
inName
ƒ alle Zustandsvariablen = false
© K. Schild, 2006 / M. Mochol 2007
22
inName: Auf "Mocha Java" warten
public void startElement(..., String elementName, ...){
if (elementName.equals("name")){ inName = true; }
else if (elementName.equals("price") && inMochaJava ){
inMJPrice = true;
<name>Mocha Java</name>
Java
inMochaJava = false; } }
<price>11.95</price>
public void characters(char
[] buf, int offset, int len) {
characters
Start
String s = new String(buf, offset, len);
if (inName && s.equals("Mocha Java")) {
inMochaJava = true;
inName
inName = false; }
else if (inMJPrice) {
System.out.println("The price of Mocha Java is: " + s);
inMJPrice = false; } }
inMochaJava
© K. Schild, 2006 / M. Mochol 2007
23
Eine bessere Alternative
public void characters(char
[] buf, int offset, int len) {
characters
String s = new String(buf, offset, len);
if (inName) { if (s.equals("Mocha Java")) {
inMochaJava = true;
<name>Mocha Java</name>
Java
inName = false; }
<price>11.95</price>
else inName = false; }
else if (inMJPrice) {
System.out.println("The price of Mocha Java is: " + s);
inMJPrice = false; } }
Start
inName
inMochaJava
© K. Schild, 2006 / M. Mochol 2007
24
inMochaJava: Auf <price> warten
public void startElement(...,
String elementName, ...){
startElemen
if (elementName.equals("name")){ inName = true; }
else if (elementName.equals("price") && inMochaJava ){
inMJPrice = true;
<name>Mocha Java</name>
inMochaJava = false; } }
<price>11.95</price>
<price>
public void characters(char [] buf, int offset, int len) {
String s = new String(buf, offset, len);
inName
if (inName && s.equals("Mocha Java")) {
inMochaJava = true;
inName = false; }
inMochaJava
else if (inMJPrice) {
System.out.println("The price of Mocha Java is: " + s);
inMJPrice = false; } }
inMJPrice
© K. Schild, 2006 / M. Mochol 2007
25
inMJPrice: Preis ausgeben
public void startElement(..., String elementName, ...){
if (elementName.equals("name")){ inName = true; }
else if (elementName.equals("price") && inMochaJava ){
inMJPrice = true;
<name>Mocha Java</name>
inMochaJava = false; } }
<price>11.95</price>
11.95
public void characters(char
[] buf, int offset, int len) {
characters
String s = new String(buf, offset, len);
Start
if (inName && s.equals("Mocha Java")) {
inMochaJava = true;
inName = false; }
inMJPrice
else if (inMJPrice) {
System.out.println("The price of Mocha Java is: " + s);
inMJPrice = false; } }
print(s)
© K. Schild, 2006 / M. Mochol 2007
26
Fehlerbehandlung
<priceList>
<coffee>
<name>
Mocha Java
</name>
<name>
MS Java
</name>
<price>
11.95
</price>
</coffee>
</priceList>
© K. Schild, 2006 / M. Mochol 2007
Start
inName
startElement =
"name"?
characters = "Mocha Java"?
inMochaJava
startElement = "price"?
inMJPrice
characters = "s"?
print(s)
27
Fehlerbehandlung
public void startElement(..., String elementName, ...){
if (elementName.equals("name")){ inName = true; }
else if (elementName.equals("price") &&
inMochaJava ){
<name>Mocha Java</name>
inMJPrice = true;
inMochaJava = false; } }
<name>MS Java</name>
ƒ inMochaJava erwartet <price>
<price>11.95</price>
ƒ kommt stattdessen <name>, wird
aktueller Zustand inMochaJava nicht
verändert
ƒ kommt danach <price>, wird aktueller
Zustand inMJPrice
Ö Preis von MS Java wird ausgegeben!
© K. Schild, 2006 / M. Mochol 2007
inName
inMochaJava
inMJPrice
28
Fehlerbehandlung
ƒ SAX-Parser überprüft immer Wohlgeformtheit eines
XML-Dokumentes.
ƒ kann aber auch die Zulässigkeit bzgl. einer DTD oder
eines Schema überprüfen
ƒ Schema kann z.B. (name price)+ verlangenf
Ö Syntax- und Strukturfehler kann bereits der SAX-Parser
abfangen
Ö Callback-Methoden können dann von wohlgeformten
und zulässigen Dokument ausgehen.
© K. Schild, 2006 / M. Mochol 2007
29
Vor- und Nachteile von SAX
+ sehr effizient, auch bei großen XML-Dokumenten
– Kontext (Parse-Baum) muss von Anwendung selbst
verwaltet werden.
– abstrahiert nicht von XML-Syntax
– nur Parsen möglich, keine Modifikation oder Erstellung
von XML-Dokumenten
© K. Schild, 2006 / M. Mochol 2007
30
Zusätzliche Schicht zum Datenzugriff
Anwendung
SAX
SAX
Datenzugriff
Datenzugriff
startElement
characters
getPriceList()
Anwendungslogik
ƒ Anwendungslogik durch zusätzliche Schicht vom
Datenzugriff trennen (nicht nur bei SAX).
ƒ Z.B. könnte getPriceList() eine Liste von Ware-PreisPaaren liefern.
ƒ sollte nicht nur von SAX-APIs, sondern auch von XMLSyntax abstrahieren
© K. Schild, 2006 / M. Mochol 2007
31
DOM-Parser
© K. Schild, 2006 / M. Mochol 2007
32
Document Object Model (DOM)
XMLParser
DOM
Anwendung
ƒ streng genommen kein Parser, sondern abstrakte
Schnittstelle zum Zugreifen, Modifizieren und Erstellen
von Parse-Bäumen
ƒ W3C-Standard
ƒ unabhängig von Programmiersprachen
ƒ nicht nur für XML-, sondern auch für HTMLDokumente
ƒ im Ergebnis aber Einschritt-Pull-Parser
© K. Schild, 2006 / M. Mochol 2007
33
DOM-Module
ƒ Level 1:
ƒ DOM-Kern (DOM Core) + Spezialisierungen für HTML und
XML;
ƒ Bearbeitung von Dokumentinhalten & Navigation innerhalb
der Dokumente
ƒ http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/
ƒ Level 2:
ƒ Namensräumen + CSS
ƒ Änderungen der Baumstruktur eines Dokuments
ƒ unterschiedliche Views von Dokumenten
ƒ Level 3 (W3C Working Draft):
ƒ Anpassungen an XML Infoset, XML Base und XPath,
© K. Schild, 2006 / M. Mochol 2007
34
DOM-Parse-Bäume
<?xml version="1.0" ?>
<priceList>
<coffee>
<name>Mocha Java</name>
<price>11.95</price>
</coffee>
</priceList>
Document Node
NodeList
Element Node: PriceList
NodeList
Element Node: coffee
ƒ Beachte: Dokument-Wurzel (Document Node) ≠ priceList
ƒ Document Node:
Node virtuelle Dokument-Wurzel, um z.B.
version="1.0" zu repräsentieren
ƒ Document Node und Element Node immer NodeList als
Kind
© K. Schild, 2006 / M. Mochol 2007
35
Rest des Parse-Baumes
<?xml version="1.0" ?>
ƒ Beachte: PCDATA wird als
<priceList>
eigener Knoten dargestellt.
<coffee>
<name>Mocha Java</name>
<price>11.95</price>
</coffee>
</priceList>
Element Node: coffee
NodeList
© K. Schild, 2006 / M. Mochol 2007
Element Node: name
Element Node: price
NodeList
NodeList
Text Node: Mocha Java
Text Node: 11.95
36
Navigationsmodell
parentNode
previousSibling
Node
nextSibling
childNodes
firstChild
lastChild
direkter Zugriff über Namen möglich: getElementsByTagName
© K. Schild, 2006 / M. Mochol 2007
37
Beispiel
<priceList>
<coffee>
<name>
Mocha Java
</name>
<price>
11.95
</price>
</coffee>
</priceList>
© K. Schild, 2006 / M. Mochol 2007
ƒ Aufgabe: Gib den Preis von
Mocha Java aus!
ƒ Hierfür benötigen wir zwei
Dinge:
1. einen DOM-Parser
2. eine passende
Zugriffsmethode
38
Wie bekomme ich einen DOM-Parser?
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
ƒ liefert DocumentBuilderFactory
DocumentBuilder builder = factory.newDocumentBuilder();
ƒ liefert DOM-Parser
Document document = builder.parse("priceList.xml");
ƒ DOM-Parser hat Methode parse().
ƒ liefert in einem Schritt kompletten
DOM-Parse-Baum
© K. Schild, 2006 / M. Mochol 2007
39
Wie sehen die Zugriffsmethoden aus?
NodeList coffeeNodes = document.getElementsByTagName("coffee");
for (int i=0; i < coffeeNodes.getLength(); i++) {
thisCoffeeNode = coffeeNodes.item(i);
Node thisNameNode = thisCoffeeNode.getFirstChild();
String data = thisNameNode.getFirstChild().getNodeValue();
if (data.equals("Mocha Java")) {
Node thisPriceNode = thisNameNode.getNextSibling();
String price = thisPriceNode.getFirstChild().getNodeValue();
break; } }
= Java-Programm, das DOMMethoden benutzt
© K. Schild, 2006 / M. Mochol 2007
40
Interface Hierarchie
Atr
interface org.w3c.dom.
DOMImplementation
NamedNodeMap
CharacterData
Comment
Text
Document
DocumentFragment
Node
DocumentType
Element
NodeList
Entity
EntityReference
Notation
PrrocessingInstruction
© K. Schild, 2006 / M. Mochol 2007
41
org.w3c.dom.NodeList
ƒ Kinder eines bestimmten Knotens (Kollektion)
ƒ int getLength()
ÆAnzahl der Knoten in der Liste
ƒ Node item(int index)
Æ item mit dem vorgegebenen Index
© K. Schild, 2006 / M. Mochol 2007
42
org.w3c.dom.Node
ƒ Node appendChild(Node newChild) Æ Hängt einen neuen
Kindknoten an die bereits existierenden an
ƒ NodeList getChildNodes() Æ Liste mit allen Kindknoten
ƒ Node getFirstChild()
Node getLastChild()
ƒ Node getNextSibling()
Node getPreviousSibling()
Liefert eine Referenz auf den
ersten/letzen Kinderknoten zurück
Referenz auf den nachfolgenden/
vorhergehenden Bruderknoten
zurück
ƒ String getNodeValue() Æ je nach Knotentyp der Wert/Inhalt (oder
null)
© K. Schild, 2006 / M. Mochol 2007
43
org.w3c.dom.Document
ƒ Element getDocumentElement()
Æ Referenz auf das Wurzelelement des Dokuments
ƒ Element createElement(String tagName)
Æ neuer Element-Knoten mit angegebenem Namen
ƒ Text createTextNode(String data)
Æneuer Text-Knoten
ƒ DocumentTyp egetDoctype()
Æ Document Type Declaration des Dokuments
© K. Schild, 2006 / M. Mochol 2007
44
org.w3c.dom.Element
ƒ NodeList getElementsByTagName(String name)
Æ Liste von Kindelementen, die einen bestimmten Namen haben
ƒ String getAttribute(String name)
Æ Wert des Attributs mit dem angegeben Namen
ƒ Attr getAttributeNode(String name)
Æ Referenz auf das Attribut mit dem angegeben Namen zurück
ƒ void removeAttribute(String name)
Æ Löscht das Attribut mit einem bestimmten Namen
© K. Schild, 2006 / M. Mochol 2007
45
Gib mir alle coffee-Elemente!
NodeList coffeeNodes = document.getElementsByTagName("coffee");
ƒ getElementsByTagName:
direkter Zugriff auf
Elemente über ihren
Namen
ƒ egal, wo Elemente stehen
ƒ Resultat immer eine
NodeList
© K. Schild, 2006 / M. Mochol 2007
<?xml version="1.0" ?>
<priceList>
<coffee>
<name>Mocha Java</name>
<price>11.95</price>
</coffee>
</priceList>
46
Betrachte Elemente der coffee-Liste!
NodeList coffeeNodes = document.getElementsByTagName("coffee");
for (int i=0; i < coffeeNodes.getLength(); i++) {
thisCoffeeNode = coffeeNodes.item(i);
…
}
coffeeNodes.item(0)
© K. Schild, 2006 / M. Mochol 2007
<?xml version="1.0" ?>
<priceList>
<coffee>
<name>Mocha Java</name>
<price>11.95</price>
</coffee>
</priceList>
47
Gib mir erstes Kind von coffee!
NodeList coffeeNodes = document.getElementsByTagName("coffee");
for (int i=0; i < coffeeNodes.getLength(); i++) {
thisCoffeeNode = coffeeNodes.item(i);
Node thisNameNode = thisCoffeeNode.getFirstChild();
String data = thisNameNode.getFirstChild().getNodeValue();
if (data.equals("Mocha Java")) {
Node thisPriceNode = thisCoffeeNode.getNextSibling();
<?xml version="1.0" ?>
String price = thisPriceNode.getFirstChild().getNodeValue();
<priceList>
break; } }
<coffee>
firstChild
<name>Mocha Java</name>
<price>11.95</price>
</coffee>
</priceList>
© K. Schild, 2006 / M. Mochol 2007
48
Gib mir den Inhalt von name!
NodeList coffeeNodes = document.getElementsByTagName("coffee");
for (int i=0; i < coffeeNodes.getLength(); i++) {
thisCoffeeNode = coffeeNodes.item(i);
Node thisNameNode = thisCoffeeNode.getFirstChild();
String data = thisNameNode.getFirstChild().getNodeValue();
if (data.equals("Mocha Java")) {
Node thisPriceNode = thisCoffeeNode.getNextSibling();
<?xml version="1.0" ?>
String price = thisPriceNode.getFirstChild().getNodeValue();
<priceList>
break; } }
firstChild
<coffee>
Element Node: coffee
<name>Mocha Java</name>
NodeList
<price>11.95</price>
Element Node: name
Element Node: price
</coffee>
NodeList
NodeList
Text Node: Mocha Java
Text Node: 11.95 </priceList>
© K. Schild, 2006 / M. Mochol 2007
49
Gib mir das Geschwister-Element!
NodeList coffeeNodes = document.getElementsByTagName("coffee");
for (int i=0; i < coffeeNodes.getLength(); i++) {
thisCoffeeNode = coffeeNodes.item(i);
Node thisNameNode = thisCoffeeNode.getFirstChild();
String data = thisNameNode.getFirstChild().getNodeValue();
if (data.equals("Mocha Java")) {
Node thisPriceNode = thisNameNode.getNextSibling();
String price = thisPriceNode.getFirstChild().getNodeValue();
<?xml version="1.0" ?>
<priceList>
break; } }
<coffee>
Element Node: coffee
nextSibling <name>Mocha Java</name>
NodeList
<price>11.95</price>
Element Node: name
Element Node: price
NodeList
NodeList
</coffee>
Text Node: Mocha Java
Text Node: 11.95
</priceList>
© K. Schild, 2006 / M. Mochol 2007
50
Gib mir den Inhalt von price!
<?xml version="1.0" ?>
NodeList coffeeNodes = document.getElementsByTagName("coffee");
<priceList>
for (int i=0; i < coffeeNodes.getLength(); i++) {
<coffee>
thisCoffeeNode = coffeeNodes.item(i);
<name>Mocha Java</name>
Node thisNameNode = thisCoffeeNode.getFirstChild();
<price>11.95</price>
</coffee>
String data = thisNameNode.getFirstChild().getNodeValue();
firstChild
</priceList>
if (data.equals("Mocha Java")) {
Node thisPriceNode = thisNameNode.getNextSibling();
String price = thisPriceNode.getFirstChild().getNodeValue();
break; } }
Element Node: coffee
NodeList
© K. Schild, 2006 / M. Mochol 2007
Element Node: name
Element Node: price
NodeList
NodeList
Text Node: Mocha Java
Text Node: 11.95
51
Vor- und Nachteile von DOM
+ Kontext (Parse-Baum) muss nicht von Anwendung
verwaltet werden.
+ einfache Navigation im Parse-Baum
+ direkter Zugriff auf Elemente über ihre Namen
+ nicht nur Parsen, sondern auch Modifikation und
Erstellung von XML-Dokumenten
– speicherintensiv
– abstrahiert nicht von XML-Syntax
© K. Schild, 2006 / M. Mochol 2007
52
SAX oder DOM?
SAX
ereignis-orientierter Ansatz
DOM
modell-orientierter Ansatz
vollständige Umsetzung in eine
Baumstruktur
mehrere Verarbeitungsmöglichkeiten
XML-Dokument als
Eingabestrom (StreamingVerfahren)
schnelle Verarbeitung von großen
XML-Dokumenten
XML-Dokument vollständig im
Speicher (Baummodell des
Dokuments )
langsame Verarbeitung von großen
XML-Dokumenten
wenig Hauptspeicher benötigt
mehr Hauptspeicher benötigt
nach dem Einlesen kann auf alle
Teilstrukturen des XML-Dokuments
zugegriffen werden
© K. Schild, 2006 / M. Mochol 2007
53
Schema-Übersetzer
© K. Schild, 2006 / M. Mochol 2007
54
Schema-Übersetzer
Datenabstraktion
XMLSchema
Übersetzen
Va
l
Instanz
XMLDokument
id
i
JavaKlassen
er
en
Instanzen
Deserialisieren
Serialisieren
JavaObjekte
ƒ Klassen/Methoden
werden generiert.
ƒ Zweck: Schnittstelle,
die von XML
abstrahiert
ƒ Lesen, Modifizieren
und Erstellen von
XML-Dokumenten
ƒ JAXB:
JAXB Java Architecture for XML Binding
ƒ Teil von Java WSDP 2.0
© K. Schild, 2006 / M. Mochol 2007
55
Beispiel
<priceList>
<coffee>
<name>Mocha Java</name>
<price>11.95</price>
</coffee>
</priceList>
zugehöriges XMLSchema
JAXB
public interface PriceList {
java.util.List getCoffee();
getCoffee
public interface CoffeeType {
String getName();
getName
void setName(String
value)
setName
java.math.BigDecimal getPrice();
getPrice
void setPrice(java.math.BigDecimal
value) } }
setPrice
© K. Schild, 2006 / M. Mochol 2007
56
Übersetzung von xsd:choice
<xs:element name="BoolCommentOrValue">
<xs:complexType>
<xs:choice>
<xs:element name="bool" type="xs:boolean"/>
<xs:element name="comment" type="xs:string"/>
<xs:element name="value" type="xs:int"/>
</xs:choice>
</xs:complexType>
</xs:element>
ƒ Wie kann dieser Datentyp nach Java übersetzt werden?
© K. Schild, 2006 / M. Mochol 2007
57
Übersetzung von xsd:choice
<xs:element name="BoolCommentOrValue">
<xs:complexType>
public interface BoolCommentOrValue {
<xs:choice>
int getValue();
getValue
<xs:element name="bool" type="xs:boolean"/>
void setValue(int
value);
setValue
<xs:element name="comment"
type="xs:string"/>
boolean
isSetValue();
isSetValue
<xs:element name="value" type="xs:int"/>
java.lang.String getComment();
getComment
</xs:choice>
void setComment(java.lang.String value);
</xs:complexType>
boolean isSetComment();
isSetComment
</xs:element>
boolean getBool();
getBool
void setBool(boolean
value);
setBoo
boolean isSetBool();
isSetBool
Object getContent();
getContent
boolean isSetContent();
isSetContent
void unSetContent();
unSetContent }
© K. Schild, 2006 / M. Mochol 2007
58
Vor- und Nachteile von JAXB
+
+
+
+
+
bessere Performance bei komplexen Aufgaben
übersichtlicher und robuster Æ weniger fehleranfällig
geringerer Wartungsaufwand
bessere Skalierbarkeit für steigenden Funktionsumfang.
Schnittstelle, die von XML abstrahiert
- Keine Unterstützung der Typsubstitution
© K. Schild, 2006 / M. Mochol 2007
59
Warum noch XML lernen?
ƒ Schema-Übersetzer: XML-Schema kann in Java- oder
C#-Klassen übersetzt werden.
ƒ Hiermit können XML-Dokumente gelesen, modifiziert
und erstellt werden, ohne dass XML sichtbar ist.
Warum sich also noch mit XML und XMLSchemata beschäftigen?
© K. Schild, 2006 / M. Mochol 2007
60
Typisches E-Business-Projekt
Zulieferer
ƒ Branchenvertreter wollen über das Internet miteinander
Geschäfte abwickeln.
ƒ Sie müssen sich auf ein Austauschformat einigen.
© K. Schild, 2006 / M. Mochol 2007
61
E-Business-Projekt: Phase I
ƒ Welche Geschäftsdaten sollen ausgetauscht werden?
ƒ Gibt es bereits einen passenden Branchenstandard?
ƒ Wie sollen die Geschäftsdaten in XML repräsentiert
werden?
ƒ Gibt es bereits einen geeigneten XML-Standard?
ƒ Ziel: Branchenstandard in Form eines XML-Schemas
Software-Architekten entwickeln gemeinsam einen
XML-basierten Branchenstandard.
© K. Schild, 2006 / M. Mochol 2007
62
E-Business-Projekt: Phase II
XML
gegeben
ƒ Branchenstandard in Form eines XML-Schemas
ƒ gemeinsames Verständnis der XML-Syntax
Aufgabe
ƒ Realisierung der Schnittstelle zwischen betriebsinterner
Software und XML-Standard.
Programmierer können Schema-Übersetzer
einsetzen und von XML abstrahieren.
© K. Schild, 2006 / M. Mochol 2007
63
Warum sich mit XML beschäftigen?
ƒ Phase I:
I Software-Architekten beschäftigen sich intensiv
mit entsprechender Branche, XML und XML-Schemata.
ƒ Phase II:
II Programmierer können Schema-Übersetzer
einsetzen und von XML abstrahieren.
Projektaufwand
Phase I
Phase II
> 80%
© K. Schild, 2006 / M. Mochol 2007
64
Wie geht es weiter?
heutige Vorlesung
;
SAX- und DOM-Parser
;
Vor- und Nachteile von SAX und DOM
;
Schema-Übersetzer
Übung nächste Woche
ƒ 3. Übung: XML Schema
Vorlesung nächste Woche
ƒ Transformation von XML-Dokumenten mit XSLT
© K. Schild, 2006 / M. Mochol 2007
65
Herunterladen