Verarbeitung mit SAX- und DOM

Werbung
Lernziele
ƒ Welche verschiedenen XML-Parser gibt es?
ƒ Was sind ihre Vor- und Nachteile?
ƒ Was sind Schema-Übersetzer?
Verarbeitung von XMLDokumenten
© Klaus Schild, 2003
1
Grundlegende Architektur
© Klaus Schild, 2003
2
Kategorien von Parser
ƒ Pull- vs. Push-Parser:
Wer hat die Kontrolle über das Parsen, die Anwendung
oder der Parser?
Zeichenkette
XMLDokument
Anwendung
Serialisierer
Parser
ƒ Einschritt- vs. Mehrschritt-Parser (engl. one-step vs. multistep parsing):
standardisierte
APIs
Wird das XML-Dokument in einem Schritt vollständig
geparst oder Schritt für Schritt analysiert?
ƒ Möglichst immer standardisierte APIs verwenden!
ƒ Parser: Analysiert XML-Dokument und erstellt Parse-Baum mit
Tags, Text-Inhalten und Attribut-Wert-Paaren als Knoten.
ƒ Beachte: Kategorien unabhängig voneinander, können
kombiniert werden
ƒ Serialisierer: Generiert aus bestimmter Datenstruktur ein XMLDokument.
© Klaus Schild, 2003
3
PullPull-Parser
© Klaus Schild, 2003
4
PushPush-Parser
nächste Einheit?
Pull-Parser
geparste Einheit
Anwendung
Push-Parser
geparste Einheit
Anwendung
ƒ Anwendung hat die Kontrolle über das Parsen.
ƒ Parser hat die Kontrolle über das Parsen.
ƒ Analyse der nächsten syntaktischen Einheit muss von der
Anwendung aktiv angefordert werden.
ƒ Sobald der Parser eine syntaktische Einheit analysiert
hat, benachrichtigt er die Anwendung und übergibt die
entsprechende Analyse.
ƒ Beachte: „Pull” bezieht sich auf die Perspektive der
Anwendung.
© Klaus Schild, 2003
ƒ Beachte: „Push” bezieht sich wiederum auf die
Perspektive der Anwendung.
5
© Klaus Schild, 2003
6
1
XMLXML-Parser
One-step
Multi-step
JAXP
DOM
Pull
SAX-Parser
Push
SAX
ƒ JAXP: Java API for XML
Processing
ƒ DOM: Document Object Model
ƒ SAX: Simple API for XML
© Klaus Schild, 2003
7
Simple API for XML (SAX)
© Klaus Schild, 2003
8
Ereignisbasiertes Parsen mit SAX
ƒ standardisiertes API für Mehrschritt-Push-Parsen von
XML-Dokumenten
SAX-Parser
ƒ ursprünglich nur Java-API, inzwischen werden aber auch
viele andere Sprachen unterstützt
ƒ kein W3C-Standard, sondern de facto Standard
Ereignis: neue
syntaktische Einheit
geparst
Aufforderung
zum Parsen
Î http://www.saxproject.org/
Event Handler
Anwendung
© Klaus Schild, 2003
9
Beispiel für ereignisbasiertes Parsen
<priceList>
<priceList>
<coffee>
<coffee>
<name>
<name>
MochaJava
Java
Mocha
</name>
</name>
<price>
<price>
11.95
11.95
</price>
</price>
</coffee>
</coffee>
</priceList>
</priceList>
© Klaus Schild, 2003
10
CallbackCallback-Methoden
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.
ƒ startElement, endElement und characters werden Call-BackMethoden genannt, weil sie vom Parser aufgerufen
werden.
ƒ für jede syntaktische Struktur in XML eine eigene
Callback-Methode
ƒ Die Standard-Implementierung der Call-Back-Methoden
(DefaultHandler) tut jeweils nichts.
ƒ Standard-Implementierungen können aber entsprechend
den Erfordernissen überschrieben werden.
ƒ Sobald eine Einheit geparst wurde, wird die Anwendung
benachrichtigt (Ereignisfluss).
ƒ Beachte: Es wird kein Parse-Baum aufgebaut!
© Klaus Schild, 2003
11
© Klaus Schild, 2003
12
2
Beispiel
<priceList>
<priceList>
<coffee>
<coffee>
<name>
<name>
MochaJava
Java
Mocha
</name>
</name>
<price>
<price>
11.95
11.95
</price>
</price>
</coffee>
</coffee>
</priceList>
</priceList>
Ein SAXSAX-Parser
ƒ Aufgabe: Gib des Preis von
Mocha Java aus!
SAXParserFactoryfactory
factory==SAXParserFactory.newInstance();
SAXParserFactory.newInstance();
SAXParserFactory
SAXParsersaxParser
saxParser==factory.newSAXParser();
factory.newSAXParser();
SAXParser
saxParser.parse("priceList.xml",handler);
handler);
saxParser.parse("priceList.xml",
ƒ SAXParserFactory.newInstance() liefert eine
SAXParserFactory.
ƒ Hierfür benötigen wir zwei
Dinge:
ƒ Die Methode newSAXParser() liefert einen SAXParser mit
einer Methode parse().
1. einen SAX-Parser
2. passende CallbackMethoden
ƒ priceList.xml: die zu parsende Datei (kann auch eine URL
oder ein Stream sein)
ƒ handler: Instanz von DefaultHandler, implementiert die
Callback-Funktionen
© Klaus Schild, 2003
13
© Klaus Schild, 2003
Exkurs: Factory Method
Die CallbackCallback-Methoden
ƒ Design Pattern aus „Design Patterns“ von Gamma, Helm,
Johnson, Vlissides (1995)
<priceList>
<priceList>
<coffee>
<coffee>
<name>
<name>
ƒ liefert ein Objekt
MochaJava
Java
Mocha
</name>
</name>
<price>
<price>
11.95
11.95
</price>
</price>
</coffee>
</coffee>
</priceList>
</priceList>
ƒ Objekt ist Instanz einer abstrakten Klasse oder einem
Interface.
ƒ wird von mehreren Klassen implementiert
ƒ Beispiel: Iterator i = list.iterator();
ƒ Beispiel: SAXParser saxParser = factory.newSAXParser();
Aufgabe: Gib den
Preis von Mocha
Java aus!
© Klaus Schild, 2003
15
Die CallbackCallback-Methoden
14
Start
startElement = name?
inName
characters = Mocha Java?
inMochaJava
startElement = price?
inPrice
characters = s?
print(s)
© Klaus Schild, 2003
16
Auf <name>
name> warten
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...)
...){{
public
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif(elementName.equals("price")
(elementName.equals("price")&&
&&inMochaJava
inMochaJava){
){
else
inPrice==true;
true;
inPrice
inName==false;
false; }}}}
inName
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...){
...){
public
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif(elementName.equals("price")
(elementName.equals("price")&&
&&inMochaJava
inMochaJava){
){
else
inPrice==true;
true;
inPrice
<name>MochaJava</name>
Java</name>
<name>Mocha
inName==false;
false; }}}}
inName
<price>11.95</price>
<price>11.95</price>
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,int
intoffset,
offset,int
intlen)
len){{
public
Stringss==new
newString(buf,
String(buf,offset,
offset,len);
len);
String
(inName&&
&&s.equals("Mocha
s.equals("MochaJava"))
Java")){{
ifif(inName
inMochaJava==true;
true;
inMochaJava
inName==false;
false; }}
inName
elseifif(inPrice)
(inPrice){{
else
System.out.println("Theprice
priceof
ofMocha
MochaJava
Javais:
is:""++s);
s);
System.out.println("The
inMochaJava==false;
false;
inMochaJava
inPrice==false;
false; }} }}
inPrice
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,int
intoffset,
offset,int
intlen)
len){{
public
Stringss==new
newString(buf,
String(buf,offset,
offset,len);
len);
String
(inName&&
&&s.equals("Mocha
s.equals("MochaJava"))
Java")){{
ifif(inName
inMochaJava==true;
true;
inMochaJava
inName==false;
false; }}
inName
elseifif(inPrice)
(inPrice){{
else
System.out.println("Theprice
priceof
ofMocha
MochaJava
Javais:
is:""++s);
s);
System.out.println("The
inMochaJava==false;
false;
inMochaJava
inPrice==false;
false; }} }}
inPrice
© Klaus Schild, 2003
17
© Klaus Schild, 2003
Start
inName
18
3
Auf "Mocha Java" warten
Auf <price>
price> warten
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...){
...){
public
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif(elementName.equals("price")
(elementName.equals("price")&&
&&inMochaJava
inMochaJava){
){
else
inPrice==true;
true;
inPrice
<name>MochaJava</name>
Java</name>
<name>Mocha
inName==false;
false; }}}}
inName
<price>11.95</price>
<price>11.95</price>
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...){
...){
public
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif(elementName.equals("price")
(elementName.equals("price")&&
&&inMochaJava
inMochaJava){){
else
inPrice==true;
true;
inPrice
<name>MochaJava</name>
Java</name>
<name>Mocha
inName==false;
false; }}}}
inName
<price>11.95</price>
<price>11.95</price>
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,int
intoffset,
offset,int
intlen)
len){{
public
Stringss==new
newString(buf,
String(buf,offset,
offset,len);
len);
String
(inName&&
&&s.equals("Mocha
s.equals("MochaJava"))
Java")){{
ifif(inName
inMochaJava==true;
true;
inMochaJava
inName==false;
false; }}
inName
elseifif(inPrice)
(inPrice){{
else
System.out.println("Theprice
priceof
ofMocha
MochaJava
Javais:
is:""++s);
s);
System.out.println("The
inMochaJava==false;
false;
inMochaJava
inPrice==false;
false; }} }}
inPrice
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,int
intoffset,
offset,int
intlen)
len){{
public
Stringss==new
newString(buf,
String(buf,offset,
offset,len);
len);
String
(inName&&
&&s.equals("Mocha
s.equals("MochaJava"))
Java")){{
ifif(inName
inMochaJava==true;
true;
inMochaJava
inName==false;
false; }}
inName
elseifif(inPrice)
(inPrice){{
else
System.out.println("Theprice
priceof
ofMocha
MochaJava
Javais:
is:""++s);
s);
System.out.println("The
inMochaJava==false;
false;
inMochaJava
inPrice==false;
false; }} }}
inPrice
Start
inName
inMochaJava
© Klaus Schild, 2003
19
Den Preis ausgeben
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,int
intoffset,
offset,int
intlen)
len){{
public
Stringss==new
newString(buf,
String(buf,offset,
offset,len);
len);
String
(inName&&
&&s.equals("Mocha
s.equals("MochaJava"))
Java")){{
ifif(inName
inMochaJava==true;
true;
inMochaJava
inName==false;
false; }}
inName
elseifif(inPrice)
(inPrice){{
else
System.out.println("Theprice
priceof
ofMocha
MochaJava
Javais:
is:""++s);
s);
System.out.println("The
inMochaJava==false;
false;
inMochaJava
inPrice==false;
false; }} }}
inPrice
Start
inPrice
inPrice
© Klaus Schild, 2003
<priceList>
<priceList>
<coffee>
<coffee>
<name>
<name>
MochaJava
Java
Mocha
</name>
</name>
<name>
<name>
MSJava
Java
MS
</name>
</name>
<price>
<price>
11.95
11.95
</price>
</price>
</coffee>
</coffee>
</priceList>
</priceList>
print(s)
© Klaus Schild, 2003
21
Fehlerbehandlung
20
Start
startElement = name?
inName
characters = Mocha Java?
inMochaJava
startElement = price?
inPrice
characters = s?
print(s)
© Klaus Schild, 2003
22
Fehlerbehandlung
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...){
...){
public
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif(elementName.equals("price")
(elementName.equals("price")&&
&&inMochaJava
inMochaJava){){
else
inPrice==true;
true;
inPrice
<name>MochaJava</name>
Java</name>
<name>Mocha
inName==false;
false; }}}}
inName
<name>MSJava</name>
Java</name>
<name>MS
<price>11.95</price>
<price>11.95</price>
ƒ Kommt ein name-Element, wird der
Zustand einfach nicht verändert.
inName
ƒ Kommt danach ein price-Element,
wird der aktuelle Zustand inPrice.
inMochaJava
ƒ Dadurch wird der Preis von MS Java
ausgegeben!
© Klaus Schild, 2003
inMochaJava
Fehlerbehandlung
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...){
...){
public
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif(elementName.equals("price")
(elementName.equals("price")&&
&&inMochaJava
inMochaJava){
){
else
inPrice==true;
true;
inPrice
<name>Mocha
Java</name>
<name>Mocha Java</name>
inName==false;
false; }}}}
inName
<price>11.95</price>
<price>11.95</price>
ƒ inMochaJava erwartet price-Element
inName
ƒ Ein SAX-Parser überprüft immer die Wohlgeformtheit
eines XML-Dokumentes.
ƒ kann aber auch die Zulässigkeit bzgl. einer DTD oder
eines Schema überprüfen
ƒ Syntax- und Strukturfehler fängt bereits der SAX-Parser
ab.
ƒ Callback-Methoden können von einem wohlgeformten
und zulässigen Dokument ausgehen.
inPrice
23
© Klaus Schild, 2003
24
4
VorVor- und Nachteile von SAX
Zusätzliche Schicht zum Datenzugriff
Anwendung
+ sehr effizient, auch bei großen XML-Dateien
– Kontext (Parse-Baum) muss von der Anwendung selbst
verwaltet werden.
SAX
SAX
– abstrahiert nicht von der spezifischen XML-Syntax
startElement
characters
– nur Parsen von XML-Dokumenten möglich, keine
Modifikation oder Erstellung von Dokumenten
Datenzugriff
Datenzugriff
Anwendungslogik
getPriceList()
ƒ Immer Anwendungslogik durch spezielle Schicht von dem
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 der
XML-Syntax abstrahieren
© Klaus Schild, 2003
25
© Klaus Schild, 2003
26
Document Object Model (DOM)
XMLParser
DOM-Parser
DOM
Anwendung
ƒ W3C-Standard zum Zugreifen, Modifizieren und
Erstellen von Parse-Bäumen
ƒ nicht nur für XML-, sondern auch für HTML-Dokumente
ƒ abstrakte Schnittstelle, unabhängig von
Programmiersprachen
ƒ im Ergebnis ein Einschritt-Pull-Parser
© Klaus Schild, 2003
27
DOMDOM-ParseParse-Bäume
<?xmlversion="1.0"
version="1.0"?>
?>
<?xml
<priceList>
<priceList>
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
</priceList>
© Klaus Schild, 2003
28
DOMDOM-ParseParse-Bäume
Document Node
<?xmlversion="1.0"
version="1.0"?>
?>
<?xml
<priceList>
<priceList>
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
</priceList>
NodeList
Element Node: PriceList
NodeList
Element Node: coffee
ƒ Beachte: Text-Inhalte
werden als eigene Knoten
dargestellt.
Element Node: coffee
NodeList
Element Node: name
ƒ Beachte: In DOM ist nicht priceList die Dokument-Wurzel.
ƒ DOM führt virtuelle Dokument-Wurzel ein, um
syntaktische Einheiten außerhalb von priceList (wie
version="1.0") repräsentieren zu können.
© Klaus Schild, 2003
29
© Klaus Schild, 2003
Element Node: price
NodeList
NodeList
Text Node: Mocha Java
Text Node: 11.95
30
5
Navigationsmodell
Beispiel
<priceList>
<priceList>
<coffee>
<coffee>
<name>
<name>
parentNode
previousSibling
Node
MochaJava
Java
Mocha
</name>
</name>
<price>
<price>
11.95
11.95
</price>
</price>
</coffee>
</coffee>
</priceList>
</priceList>
nextSibling
childNodes
firstChild
lastChild
© Klaus Schild, 2003
31
ƒ Aufgabe: Gib des Preis von
Mocha Java aus!
ƒ Hierfür benötigen wir zwei
Dinge:
1. einen DOM-Parser
2. eine passende
Zugriffsmethode
© Klaus Schild, 2003
32
Ein DOMDOM-Parser
Zugriffsmethoden
DocumentBuilderFactoryfactory
factory== DocumentBuilderFactory.newInstance();
DocumentBuilderFactory.newInstance();
DocumentBuilderFactory
DocumentBuilderbuilder
builder==factory.newDocumentBuilder();
factory.newDocumentBuilder();
DocumentBuilder
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
Documentdocument
document==builder.parse("priceList.xml");
builder.parse("priceList.xml");
Document
ƒ Direkter Zugriff auf
bestimmte Elemente mit
getElementsByTagName
möglich.
ƒ DocumentBuilderFactory.newInstance() liefert eine
DocumentBuilderFactory.
ƒ Die Methode newDocumentBuilder() von
DocumentBuilderFactory liefert einen DOM-Parser.
ƒ Resultat ist eine NodeList.
<?xmlversion="1.0"
version="1.0"?>
?>
<?xml
<priceList>
<priceList>
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
</priceList>
ƒ Der DOM-Parser hat eine Methode parse().
© Klaus Schild, 2003
33
Zugriffsmethoden
34
Zugriffsmethoden
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
for(int
(inti=0;
i=0;ii<<coffeeNodes.getLength();
coffeeNodes.getLength();i++)
i++){{
for
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
<?xmlversion="1.0"
version="1.0"?>
?>
…
<?xml
…
<priceList>
<priceList>
}
}
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
coffeeNodes.item(0)
</priceList>
© Klaus Schild, 2003
© Klaus Schild, 2003
35
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
for(int
(inti=0;
i=0;ii<<coffeeNodes.getLength();
coffeeNodes.getLength();i++)
i++){{
for
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
NodethisNameNode
thisNameNode==thisCoffeeNode.getFirstChild();
thisCoffeeNode.getFirstChild();
Node
Stringdata
data==thisNameNode.getFirstChild().getNodeValue();
thisNameNode.getFirstChild().getNodeValue();
String
(data.equals("MochaJava"))
Java")){{
ifif(data.equals("Mocha
NodethisPriceNode
thisPriceNode==thisCoffeeNode.getNextSibling();
thisCoffeeNode.getNextSibling();
Node
<?xmlversion="1.0"
version="1.0"?>
?>
<?xml
Stringprice
price== thisPriceNode.getFirstChild().getNodeValue();
thisPriceNode.getFirstChild().getNodeValue();
String
<priceList>
<priceList>
break;}}}}
break;
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
firstChild
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
</priceList>
© Klaus Schild, 2003
36
6
DOMDOM-Methoden
DOMDOM-Methoden
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
for(int
(inti=0;
i=0;ii<<coffeeNodes.getLength();
coffeeNodes.getLength();i++)
i++){{
for
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
for(int
(inti=0;
i=0;ii<<coffeeNodes.getLength();
coffeeNodes.getLength();i++)
i++){{
for
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
NodethisNameNode
thisNameNode==thisCoffeeNode.getFirstChild();
thisCoffeeNode.getFirstChild();
Node
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
NodethisNameNode
thisNameNode==thisCoffeeNode.getFirstChild();
thisCoffeeNode.getFirstChild();
Node
Stringdata
data==thisNameNode.getFirstChild().getNodeValue();
thisNameNode.getFirstChild().getNodeValue();
String
(data.equals("MochaJava"))
Java")){{
ifif(data.equals("Mocha
Stringdata
data==thisNameNode.getFirstChild().getNodeValue();
thisNameNode.getFirstChild().getNodeValue();
String
(data.equals("MochaJava"))
Java")){{
ifif(data.equals("Mocha
NodethisPriceNode
thisPriceNode==thisCoffeeNode.getNextSibling();
thisCoffeeNode.getNextSibling();
Node
<?xmlversion="1.0"
version="1.0"?>
?>
<?xml
Stringprice
price== thisPriceNode.getFirstChild().getNodeValue();
thisPriceNode.getFirstChild().getNodeValue();
String
<priceList>
<priceList>
firstChild
break;
}
}
break; } }
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
ƒ Beachte: getFirstChild() liefert
<price>11.95</price>
<price>11.95</price>
</coffee>
den Text-Knoten, nicht dessen
</coffee>
</priceList>
Inhalt „Mocha Java“!
</priceList>
© Klaus Schild, 2003
37
DOMDOM-Methoden
© Klaus Schild, 2003
38
VorVor- und Nachteile von DOM
<?xmlversion="1.0"
version="1.0"?>
?>
<?xml
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
<priceList>
<priceList>
for
(int
i=0;
i
<
coffeeNodes.getLength();
i++)
{
for (int i=0; i < coffeeNodes.getLength(); i++)<coffee>
{
<coffee>
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
<name>MochaJava</name>
Java</name>
<name>Mocha
NodethisNameNode
thisNameNode==thisCoffeeNode.getFirstChild();
thisCoffeeNode.getFirstChild();
<price>11.95</price>
Node
<price>11.95</price>
</coffee>
Stringdata
data==thisNameNode.getFirstChild().getNodeValue();
thisNameNode.getFirstChild().getNodeValue();
</coffee>
String
firstChild
</priceList>
</priceList>
if
(data.equals("Mocha
Java"))
{
if (data.equals("Mocha Java")) {
NodethisPriceNode
thisPriceNode==thisNameNode.getNextSibling();
thisNameNode.getNextSibling();
Node
+ Kontext (Parse-Baum) muss nicht von der Anwendung
verwaltet werden.
+ direkter Zugriff auf Elemente und Attribute über ihre
Namen (unabhängig von deren Position) möglich
+ Nicht nur Parsen von XML-Dokumenten möglich,
sondern auch Modifikation und Erstellung von
Dokumenten.
Stringprice
price== thisPriceNode.getFirstChild().getNodeValue();
thisPriceNode.getFirstChild().getNodeValue();
String
break;}}}}
break;
© Klaus Schild, 2003
NodethisPriceNode
thisPriceNode==thisNameNode.getNextSibling();
thisNameNode.getNextSibling();
Node
Stringprice
price== thisPriceNode.getFirstChild().getNodeValue();
thisPriceNode.getFirstChild().getNodeValue();
<?xmlversion="1.0"
version="1.0"?>
?>
String
<?xml
<priceList>
break;}}}}
<priceList>
break;
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
nextSibling
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
</priceList>
– speicherintensiv
39
© Klaus Schild, 2003
40
SAX oder DOM?
ƒ SAX ist geeignet, um gezielt bestimmte Teile von XMLDokumenten herauszufiltern, ohne zu einem späteren
Zeitpunkt andere Teile des Dokumentes zu benötigen.
ƒ DOM ist geeignet, um auf unterschiedliche Teile eines
XML-Dokumentes zu verschiedenen Zeitpunkten
zuzugreifen.
Schema-Übersetzer
ƒ DOM ist zum Erstellen und Modifizieren von
Dokumenten geeignet, SAX ist hierfür ungeeignet.
© Klaus Schild, 2003
41
© Klaus Schild, 2003
42
7
Beispiel
SchemaSchema-Übersetzer
<priceList>
<priceList>
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
</priceList>
Datenabstraktion
XMLSchema
Übersetzen
Va
Instanz
XMLDokument
lid
ie
re
JavaKlassen
Instanzen
n
JavaObjekte
Î Java Architecture for XML Binding (JAXB)
© Klaus Schild, 2003
43
Marshalling/
Marshalling/Unmarshalling
Serialisieren
© Klaus Schild, 2003
44
Warum sich noch mit XML beschäftigen?
ƒ Mit Hilfe eines Schema-Übersetzers kann eine
Anwendung vollständig von XML abstrahieren.
marshal
XMLDokument
JAXB
publicinterface
interfacePriceList
PriceList{{
public
java.util.ListgetCoffee();
getCoffee();
java.util.List
publicinterface
interfaceCoffeeType
CoffeeType{{
public
StringgetName();
getName();
String
voidsetName(String
setName(Stringvalue)
value)
void
java.math.BigDecimalgetPrice();
getPrice();
java.math.BigDecimal
voidsetPrice(java.math.BigDecimal
setPrice(java.math.BigDecimalvalue)
value)}}}}
void
Deserialisieren
Serialisieren
PriceList-Schema
ƒ Voraussetzung: XML-Schema oder eine DTD
JavaObjekte
ƒ Ein Anwendungsentwickler kann das XML-Schema in
Java oder C# übersetzen und mit dem generierten Code
XML-Dokumente lesen, modifizieren und erstellen.
Deserialisieren
unmarshal
ƒ Serialisieren (marshalling) generiert aus Datenstrukturen
der Anwendung ein XML-Dokument.
ƒ to marshal = ordnen (Fakten), antreten lassen (Soldaten)
ƒ Deserialisieren (unmarshalling) erstellt keinen ParseBaum, sondern Java-Objekte mit Methoden zum Zugreifen
und Modifizieren der Daten.
© Klaus Schild, 2003
45
Typisches EE-BusinessBusiness-Projekt
Warumsollte
solltesich
sichalso
alsoein
einAnwendungsentwickler
Anwendungsentwickler
Warum
überhauptnoch
nochmit
mitXML
XMLoder
oderXML-Schemata
XML-Schemata
überhaupt
beschäftigen?
beschäftigen?
© Klaus Schild, 2003
46
Typisches EE-BusinessBusiness-Projekt: Phase I
ƒ Welche Geschäftsdaten sollen ausgetauscht werden?
ƒ Gibt es bereits einen passenden Branchenstandard (nicht
unbedingt XML-basiert)?
Zulieferer
ƒ Wie sollen diese Geschäftsdaten in XML repräsentiert
werden?
ƒ Gibt es bereits einen geeigneten XML-Standard?
ƒ Ziel: Branchenstandard in Form eines XML-Schemas
ƒ Branchenvertreter wollen miteinander Geschäfte über
das Internet machen.
Software-Architektenentwickeln
entwickeln
Software-Architekten
gemeinsameinen
einen XML-basierten
XML-basierten
gemeinsam
Branchenstandard(=
(=XML-Schema).
XML-Schema).
Branchenstandard
ƒ Sie müssen sich auf ein Austauschformat einigen.
© Klaus Schild, 2003
47
© Klaus Schild, 2003
48
8
Typisches EE-BusinessBusiness-Projekt: Phase II
Warum sich noch mit XML beschäftigen?
ƒ Phase I: Software-Architekten beschäftigen sich intensiv
mit entsprechender Branche, XML und XML-Schemata.
XML
ƒ Phase II: Programmierer können Schema-Übersetzer
einsetzen und von XML abstrahieren.
ƒ Branchenstandard liegt in Form eines XML-Schemas vor.
ƒ Es gibt ein gemeinsames Verständnis der verwendeten
XML-Syntax.
ƒ Aufgabe: Realisierung der Schnittstelle zwischen
betriebsinterner Software und dem XML-Standard.
Programmiererkönnen
könnenSchema-Übersetzer
Schema-Übersetzereinsetzen
einsetzen
Programmierer
undvon
vonder
derXML-Syntax
XML-Syntaxabstrahieren.
abstrahieren.
und
© Klaus Schild, 2003
49
© Klaus Schild, 2003
50
9
Herunterladen