XML-Parser

Werbung
Heutige Vorlesung
ƒ Welche XML-Parser gibt es?
ƒ Was sind ihre Vor- und Nachteile?
ƒ Was sind Schema-Übersetzer?
XML-Parser
© Klaus Schild, 2004
1
Grundlegende Architektur
© Klaus Schild, 2004
2
Kategorien von Parser
ƒ PullPull- vs. PushPush-Parser
Wer hat Kontrolle über das Parsen: die Anwendung oder
der Parser?
Zeichenkette
XMLDokument
Anwendung
Serialisierer
Parser
ƒ EinschrittEinschritt- vs. MehrschrittMehrschritt-Parser (one-step vs. multi-step
parsing)
standardisierte
APIs
Wird das XML-Dokument in einem Schritt vollständig
geparst oder Schritt für Schritt?
ƒ Möglichst standardisierte APIs verwenden!
ƒ Parser:
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:
Serialisierer Generiert aus bestimmter Datenstruktur ein XMLDokument.
© Klaus Schild, 2004
3
PullPull-Parser
© Klaus Schild, 2004
4
PushPush-Parser
nächste Einheit?
Pull-Parser
geparste Einheit
Anwendung
Push-Parser
geparste Einheit
Anwendung
ƒ Anwendung hat Kontrolle über das Parsen.
ƒ Parser hat Kontrolle über das Parsen.
ƒ Analyse der nächsten syntaktischen Einheit muss aktiv
angefordert werden.
ƒ Sobald der Parser eine syntaktische Einheit analysiert
hat, übergibt er die entsprechende Analyse.
ƒ Beachte: „Pull” bezieht sich auf die Perspektive der
Anwendung.
ƒ Beachte: „Push” bezieht sich wiederum auf die
Perspektive der Anwendung.
© Klaus Schild, 2004
5
© Klaus Schild, 2004
6
1
XMLXML-Parser
One-step
Multi-step
JAXP
DOM
Pull
SAX-Parser
Push
SAX
ƒ JAXP:
JAXP Java API for XML
Processing
ƒ DOM:
DOM Document Object Model
ƒ SAX:
SAX Simple API for XML
© Klaus Schild, 2004
7
Simple API for XML (SAX)
© Klaus Schild, 2004
8
Ereignisbasiertes Parsen
ƒ Mehrschritt-Push-Parser für XML
ƒ standardisiertes API
SAX-Parser
ƒ ursprünglich nur Java-API, inzwischen werden aber auch
viele andere Sprachen unterstützt
Ereignis: neue
syntaktische Einheit
geparst
einmaliges
Anstoßen des
Parsens
ƒ kein W3C-Standard, sondern de facto Standard
Î http://www.saxproject.org/
Event Handler
Anwendung
© Klaus Schild, 2004
9
Beispiel
<priceList>
<priceList>
<coffee>
<coffee>
<name>
<name>
MochaJava
Java
Mocha
</name>
</name>
<price>
<price>
11.95
11.95
</price>
</price>
</coffee>
</coffee>
</priceList>
</priceList>
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.
ƒ Ereignisfluss:
Ereignisfluss Sobald Einheit geparst wurde, wird
Anwendung benachrichtigt.
ƒ CallbackCallback-Methoden:
Methoden Methoden des Event-Handlers (also
der Anwendung), die vom Parser aufgerufen werden.
ƒ für jede syntaktische Einheit in XML eigene CallbackMethode:
ƒ startElement
ƒ endElement
ƒ characters
ƒ DefaultHandler:
DefaultHandler Standard-Implementierung der CallbackMethoden, tun jeweils nichts.
ƒ Standard-Implementierungen können aber überschrieben
werden.
ƒ Beachte: Es wird kein Parse-Baum aufgebaut!
© Klaus Schild, 2004
© Klaus Schild, 2004
11
© Klaus Schild, 2004
12
2
Beispiel
Wie bekomme ich einen SAXSAX-Parser?
Parser?
SAXParserFactoryfactory
factory==SAXParserFactory.newInstance();
SAXParserFactory.newInstance();
SAXParserFactory
<priceList>
<priceList>
<coffee>
<coffee>
<<name>
name>
name>
MochaJava
Java
Mocha
</name>
</name
name>
>
</
<<price>
price>
price>
11.95
11.95
</price>
</price
price>
>
</
</coffee>
</coffee>
</priceList>
</priceList>
ƒ Aufgabe: Gib den Preis von
Mocha Java aus!
ƒ Hierfür benötigen wir zwei
Dinge:
ƒ liefert eine SAXParserFactory
SAXParsersaxParser
saxParser==factory.newSAXParser();
factory.newSAXParser();
SAXParser
ƒ liefert einen SAXParser
saxParser.parse("priceList.xml",handler);
handler);
saxParser.parse("priceList.xml",
1. einen SAX-Parser
2. passende CallbackMethoden
ƒ stößt SAX-Parser an
ƒ priceList.xml: zu parsende Datei, kann auch URL oder
Stream sein
ƒ handler: Instanz von DefaultHandler, implementiert
Callback-Funktionen
© Klaus Schild, 2004
13
© Klaus Schild, 2004
14
Exkurs: Factory Method
Wie sehen die CallbackCallback-Methoden aus?
ƒ Entwurfsmuster aus „Design Patterns“ von Gamma,
Helm, Johnson, Vlissides (1995)
<priceList>
<priceList>
<coffee>
<coffee>
<<name>
name>
name>
ƒ liefert ein Objekt
MochaJava
Java
Mocha
</name>
</name>
<<price>
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, 2004
15
Die CallbackCallback-Methoden in Java
Start
startElement = name?
inName
characters = Mocha Java?
inMochaJava
startElement = price?
inPrice
characters = s?
print(s)
© Klaus Schild, 2004
16
Auf <name>
name> warten
publicvoid
voidstartElement(...,
startElement(...,
StringelementName,
elementName,
...){{
public
(..., String
, ...)
startElement
elementName
(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
startElement
inName==true;
true;
ifif((elementName.equals("name")){
elementName.equals("name")){
; }}
elementName.equals("name")){ inName
true
elseifif(elementName.equals("price")
(elementName.equals("price")&&
&&inMochaJava
inMochaJava){
){
else
inPrice==true;
true;
inPrice
<name>Mocha
Java</name>
<name
name>Mocha Java</name>
inName==false;
false; }}}}
inName
<price>11.95</price>
<price>11.95</price>
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,
intoffset,
offset,
intlen)
len)
public
, int
, int
) {{
buf
offset
len
Stringss==new
newString(buf,
String(buf,
offset,
len);
String
, offset,
, len);
);
String(buf
offset
len
(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, 2004
17
© Klaus Schild, 2004
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>Mocha
Java</name>
<name>Mocha
Mocha Java</name>
Java
inName==false;
false; }}}}
inName
<price>11.95</price>
<price>11.95</price>
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...){
...){
public
startElemen
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif((elementName.equals("price")
&&inMochaJava
inMochaJava){){
else
elementName.equals("price")
elementName.equals("price") &&
inPrice==true;
true;
inPrice
;
true
<name>MochaJava</name>
Java</name>
<name>Mocha
inName==false;
false;
inName
; }}}}
false
<price>11.95</price>
<price
price>11.95</price>
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,int
intoffset,
offset,int
intlen)
len){{
public
characters
Stringss==new
newString(buf,
String(buf,offset,
offset,len);
len);
String
&&s.equals("Mocha
s.equals("MochaJava"))
Java")){{
ifif((inName
inName &&
inMochaJava==true;
true;
inMochaJava
;
true
inName==false;
false;
inName
; }}
false
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, 2004
19
Den Preis ausgeben
publicvoid
voidcharacters(char
characters(char[][]buf,
buf,int
intoffset,
offset,int
intlen)
len){{
public
characters
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)
else
inPrice)
inPrice) {{
System.out.println("Theprice
priceof
ofMocha
MochaJava
Javais:
s);
System.out.println("The
: ""++s);
isis:
inMochaJava==false;
false;
inMochaJava
;
false
inPrice==false;
false;
inPrice
; }} }}
false
Start
inPrice
21
Fehlerbehandlung
<price>11.95</price>
<price>11.95</price>
ƒ Kommt stattdessen name-Element,
wird aktueller Zustand nicht verändert.
© Klaus Schild, 2004
20
<priceList>
<priceList>
<coffee>
<coffee>
<<name>
name>
name>
MochaJava
Java
Mocha
</name>
</name>
<<name>
name>
name>
MSJava
Java
MS
</name>
</name>
<<price>
price>
price>
11.95
11.95
</price>
</price>
</coffee>
</coffee>
</priceList>
</priceList>
Start
startElement = name?
inName
characters = Mocha Java?
inMochaJava
startElement = price?
inPrice
characters = s?
print(s)
© Klaus Schild, 2004
22
Fehlerbehandlung
publicvoid
voidstartElement(...,
startElement(...,String
StringelementName,
elementName,...){
...){
public
(elementName.equals("name")){ inName
inName==true;
true; }}
ifif(elementName.equals("name")){
elseifif((elementName.equals("price")
&&inMochaJava
inMochaJava){){
else
elementName.equals("price")
elementName.equals("price") &&
inPrice==true;
true;
inPrice
;
true
<name>MochaJava</name>
Java</name>
<name>Mocha
inName==false;
false;
inName
; }}}}
false
<name>MSJava</name>
Java</name>
<name>MS
ƒ Dadurch wird Preis von MS Java
ausgegeben!
inPrice
© Klaus Schild, 2004
print(s)
© Klaus Schild, 2004
ƒ Kommt danach price-Element, wird
der aktueller Zustand inPrice.
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
11.95</price>
ƒ inMochaJava erwartet price-Element
inName
ƒ SAX-Parser überprüft immer 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.
inName
ƒ Callback-Methoden können von einem wohlgeformten
und zulässigen Dokument ausgehen.
inMochaJava
inPrice
23
© Klaus Schild, 2004
24
4
VorVor- und Nachteile von SAX
Zusätzliche Schicht zum Datenzugriff
Anwendung
+ sehr effizient, auch bei großen XML-Dokumenten
– Kontext (Parse-Baum) muss von Anwendung selbst
verwaltet werden.
Datenzugriff
Datenzugriff
SAX
SAX
– abstrahiert nicht von XML-Syntax
startElement
characters
– nur Parsen möglich, keine Modifikation oder Erstellung
von XML-Dokumenten
Anwendungslogik
getPriceList()
ƒ Immer Anwendungslogik durch zusätliche 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, 2004
25
© Klaus Schild, 2004
26
Document Object Model (DOM)
XMLParser
DOM-Parser
DOM
Anwendung
ƒ W3C-Standard
ƒ abstrakte Schnittstelle zum Zugreifen, Modifizieren und
Erstellen von Parse-Bäumen
ƒ unabhängig von Programmiersprachen
ƒ nicht nur für XML-, sondern auch für HTML-Dokumente
ƒ im Ergebnis ein Einschritt-Pull-Parser
© Klaus Schild, 2004
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, 2004
DOMDOM-ParseParse-Bäume
Document Node
<?xmlversion="1.0"
version="1.0"?>
?>
<?xml
ƒ Beachte: Text-Inhalte
<priceList>
<priceList>
werden als eigene Knoten
<coffee>
<coffee>
dargestellt.
<name>MochaJava</name>
Java</name>
<name>Mocha
<price>11.95</price>
<price>11.95</price>
Element Node: coffee
</coffee>
</coffee>
</priceList>
NodeList
</priceList>
NodeList
Element Node: PriceList
NodeList
Element Node: coffee
Element Node: name
ƒ Beachte: priceList ≠ 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, 2004
28
29
© Klaus Schild, 2004
Element Node: price
NodeList
NodeList
Text Node: Mocha Java
Text Node: 11.95
30
5
Navigationsmodell
Beispiel
<priceList>
<priceList>
<coffee>
<coffee>
<<name>
name>
name>
parentNode
previousSibling
MochaJava
Java
Mocha
</name>
</name
name>
>
</
<<price>
price>
price>
11.95
11.95
</price>
</price
price>
>
</
</coffee>
</coffee>
</priceList>
</priceList>
nextSibling
Node
childNodes
firstChild
lastChild
© Klaus Schild, 2004
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, 2004
32
Wie bekomme ich einen DOMDOM-Parser?
Parser?
Wie sehen die Zugriffsmethoden aus?
DocumentBuilderFactoryfactory
factory== DocumentBuilderFactory.newInstance();
DocumentBuilderFactory.newInstance();
DocumentBuilderFactory
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
");
document.getElementsByTagName("coffee
for(int
(inti=0;
i=0;ii<<coffeeNodes.getLength();
coffeeNodes.getLength();i++)
i++){{
for
ƒ liefert DocumentBuilderFactory
DocumentBuilderbuilder
builder==factory.newDocumentBuilder();
factory.newDocumentBuilder();
DocumentBuilder
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
NodethisNameNode
thisNameNode==thisCoffeeNode.getFirstChild();
thisCoffeeNode.getFirstChild();
Node
();
thisCoffeeNode.getFirstChild
Stringdata
data==thisNameNode.getFirstChild().getNodeValue();
thisNameNode.getFirstChild().getNodeValue();
String
();
thisNameNode.getFirstChild().getNodeValue
(data.equals("MochaJava"))
Java")){{
ifif(data.equals("Mocha
ƒ liefert DOM-Parser
NodethisPriceNode
thisPriceNode==thisNameNode.getNextSibling();
thisNameNode.getNextSibling();
Node
();
thisNameNode.getNextSibling
Stringprice
price== thisPriceNode.getFirstChild().getNodeValue();
thisPriceNode.getFirstChild().getNodeValue();
String
();
thisPriceNode.getFirstChild().getNodeValue
Documentdocument
document==builder.parse("priceList.xml");
builder.parse("priceList.xml");
Document
break;}}}}
break;
ƒ DOM-Parser hat Methode parse().
Java-Programm, das
das DOMDOMJava-Programm,
Methoden benutzt
benutzt
Methoden
ƒ liefert DOM-Parse-Baum
© Klaus Schild, 2004
33
© Klaus Schild, 2004
34
Gib mir die Liste aller coffeecoffee-Elemente!
Elemente!
Betrachte alle Elemente der coffeecoffee-Liste!
Liste!
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
");
document.getElementsByTagName("coffee
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
for((int
i=0;ii<<coffeeNodes.getLength();
coffeeNodes.getLength();
i++){{
for
int i=0;
(); i++)
coffeeNodes.getLength
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
);
coffeeNodes.item(i
<?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>
coffeeNodes.item(0)
</priceList>
</priceList>
ƒ getElementsByTagName:
direkter Zugriff auf
Elemente über ihren
Namen
ƒ egal, wo Elemente stehen
ƒ Resultat ist immer eine
NodeList.
© Klaus Schild, 2004
<?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>
35
© Klaus Schild, 2004
36
6
Gib mir erstes KindKind-Element von coffee!
coffee!
Gib mir den Inhalt von name!
name!
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.getFirstChild
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, 2004
37
Stringdata
data==thisNameNode.getFirstChild().getNodeValue();
thisNameNode.getFirstChild().getNodeValue();
String
();
thisNameNode.getFirstChild().getNodeValue
(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>
Text-Knoten, nicht dessen
</coffee>
</priceList>
Inhalt „Mocha Java“!
</priceList>
© Klaus Schild, 2004
Gib mir das nächste KindKind-Element!
Gib mir den Inhalt von price!
price!
NodeListcoffeeNodes
coffeeNodes==document.getElementsByTagName("coffee");
document.getElementsByTagName("coffee");
NodeList
for(int
(inti=0;
i=0;ii<<coffeeNodes.getLength();
coffeeNodes.getLength();i++)
i++){{
for
<?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
thisCoffeeNode==coffeeNodes.item(i);
coffeeNodes.item(i);
thisCoffeeNode
NodethisNameNode
thisNameNode==thisCoffeeNode.getFirstChild();
thisCoffeeNode.getFirstChild();
Node
Stringdata
data==thisNameNode.getFirstChild().getNodeValue();
thisNameNode.getFirstChild().getNodeValue();
String
Java")){{
ifif((data.equals("Mocha
data.equals("Mocha Java"))
NodethisPriceNode
thisPriceNode==thisNameNode.getNextSibling();
thisNameNode.getNextSibling();
Node
();
thisNameNode.getNextSibling
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>
© Klaus Schild, 2004
39
VorVor- und Nachteile von DOM
Stringprice
price== thisPriceNode.getFirstChild().getNodeValue();
thisPriceNode.getFirstChild().getNodeValue();
String
();
thisPriceNode.getFirstChild().getNodeValue
break;}}}}
break;
© Klaus Schild, 2004
40
SAX oder DOM?
SAX
+ Kontext (Parse-Baum) muss nicht von Anwendung
verwaltet werden.
ƒ geeignet, um gezielt bestimmte Teile von XMLDokumenten herauszufiltern, ohne zu einem späteren
Zeitpunkt andere Teile des Dokumentes zu benötigen
+ direkter Zugriff auf Elemente und Attribute über ihre
Namen
DOM
+ nicht nur Parsen, sondern auch Modifikation und
Erstellung von XML-Dokumenten
ƒ geeignet, um auf unterschiedliche Teile eines XMLDokumentes zu verschiedenen Zeitpunkten zuzugreifen
– speicherintensiv
© Klaus Schild, 2004
38
ƒ Erstellen und Modifizieren von XML-Dokumenten
41
© Klaus Schild, 2004
42
7
SchemaSchema-Übersetzer
Datenabstraktion
XMLSchema
Schema-Übersetzer
Übersetzen
Va
Instanz
XMLDokument
lid
ie
re
n
JavaKlassen
Instanzen
Deserialisieren
Serialisieren
JavaObjekte
Java Architecture for XML Binding
(JAXB
JAXB)
© Klaus Schild, 2004
43
Beispiel
ƒ Klassen/Methoden
werden generiert.
ƒ Zweck: Schnittstelle,
die von XML-Syntax
abstrahiert.
ƒ Lesen, Modifizieren
und Erstellen von
XML-Dokumenten
möglich.
© Klaus Schild, 2004
44
Warum noch XML lernen?
<priceList>
<priceList>
<coffee>
<coffee>
<name>MochaJava</name>
Java</name>
<name>Mocha
<price>11.95</price>
<price>11.95</price>
</coffee>
</coffee>
</priceList>
</priceList>
ƒ Schema-Übersetzer: XML-Schema kann in Java- oder
C#-Klassen übersetzt werden.
PriceList-Schema
ƒ Hiermit können XML-Dokumente gelesen, modifiziert
und erstellt werden, ohne dass XML sichtbar ist.
JAXB
Warum sich
sich also
also noch
noch mit
mit XML
XML und
und XMLXMLWarum
Schemata beschäftigen?
beschäftigen?
Schemata
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
© Klaus Schild, 2004
45
Typisches EE-BusinessBusiness-Projekt
© Klaus Schild, 2004
46
Typisches EE-BusinessBusiness-Projekt: Phase I
ƒ Welche Geschäftsdaten sollen ausgetauscht werden?
ƒ Gibt es bereits einen passenden Branchenstandard?
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
Software-Architekten entwickeln
entwickeln gemeinsam
gemeinsam einen
einen
Software-Architekten
XML-basierten Branchenstandard.
Branchenstandard.
XML-basierten
ƒ Branchenvertreter wollen miteinander Geschäfte über
das Internet machen.
ƒ Sie müssen sich auf ein Austauschformat einigen.
© Klaus Schild, 2004
47
© Klaus Schild, 2004
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.
ƒ gegeben:
ƒ Branchenstandard in Form eines XML-Schemas
ƒ gemeinsames Verständnis der XML-Syntax
Projektaufwand
ƒ Aufgabe: Realisierung der Schnittstelle zwischen
betriebsinterner Software und dem XML-Standard.
PhaseII
Phase
Programmierer können
können Schema-Übersetzer
Schema-Übersetzer
Programmierer
einsetzen und
und von
von XML
XML abstrahieren.
abstrahieren.
einsetzen
© Klaus Schild, 2004
PhaseIIII
Phase
> 80%
49
© Klaus Schild, 2004
50
Wie geht es weiter?
heutige Vorlesung
;
Sax- und DOM-Parser
;
Vor- und Nachteile von SAX und DOM
;
Schema-Übersetzer
nächste Woche
ƒ Transformation von XML-Dokumenten mit XSLT
© Klaus Schild, 2004
51
9
Herunterladen