| |
Typische Anwendungsfälle & Beispiele
[ DOM &
JDOM ] ... [ Fazit ] ...
Übersicht
In diesem Abschnitt werden typische Anwendungsfälle im Bereich der XML-Verarbeitung
untersucht. Hierbei wird nach einer kurzen Beschreibung des Problems, jeweils
eine Lösung für DOM (unter Verwendung von Xerces), beziehungsweise für JDOM
angegeben. Am Ende dieser Seite finden sich Links für zwei vollständige
Beispiele.
Bestehende XML-Dokumente lesen
Ein Dokument komplett neu erzeugen
Informationen extrahieren
Die Struktur des Dokuments verändern
Das Dokument speichern
Vollständige Beispiele
Situation
Häufig möchte man aus einem eigenen Programm ein bestimmtes XML-Dokument
einlesen, um es in irgendeiner Form zu bearbeiten.
Ferner ist es häufig nötig, die zu lesenden Daten auf ihre Validität
hinsichtlich der Dokumenttypdefinition zu überprüfen.
DOM
import
org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
...
Document doc = null;
try {
DOMParser p = new
DOMParser(); //
Parser instanzieren
// Validierung anschalten
p.setFeature("http://xml.org/sax/features/validation",true);
p.parse(args[0]);
// Datei parsen
doc =
p.getDocument();
// Dokument vom Parser abholen
}
catch
(IOException
io) { //
z. B. Dateifehler
...
}
catch
(SAXException
s) { //
z. B. ungültiges XML-Dokument
...
}
...
|
JDOM
import org.jdom.input.SAXBuilder;
import org.jdom.Document;
...
Document doc = null;
try {
SAXBuilder b = new
SAXBuilder(true);
// validierenden Parser nutzen
doc = b.build(new File(args[0])); }
catch (JDOMException
j) { // nur eine Ausnahme für
alle Situationen
...
}
...
|
Fazit
Eine Schwäche von DOM besteht darin, dass das Einlesen eines Dokuments
nicht durch das W3C spezifiziert ist und damit implementierungsabhängig bleibt.
Dadurch ist die Portabilität der Programme in gewisser Weise eingeschränkt, da
ein Wechsel einer DOM-Implementierung nicht immer ohne Codeänderungen
durchgeführt werden kann. Auch ansonsten wirkt das JDOM-Programmfragment
deutlich natürlicher und intuitiver.
Situation
Möchte man kein bereits vorhandenes Dokument lesen, dann steht man
vielleicht vor dem Problem ein Dokument von Grund auf neu zu erzeugen und mit
Elementen, Attributen, etc. zu füllen. Die unten stehenden Programmfragmente
erzeugen jeweils ein XML-Dokument, welches der folgenden Struktur
entspricht.
<linux-config>
<window-manager default="true">
<name>Enlightenment</name>
</window-manager>
<!-- etc -->
</linux-config> |
DOM
import
org.apache.xerces.dom.DOMImplementationImpl;
import org.w3c.dom.*;...
DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
// Dokumentenobjekt erzeugen
Document doc = impl.createDocument(null,
"Linux", null);
// Erzeugen des Wurzelelements.
Element root =
doc.createElement("linux-config");
// erstes Element und Kindknoten erzeugen und an die
Wurzel hängen
Element wm = doc.createElement("window-manager");
Text name = doc.createTextNode("Enlightenment");
wm.setAttribute("default", "true");
wm.appendChild(name);
root.appendChild(wm);
// Kommentar erzeugen und anhängen
root.appendChild(doc.createComment(" etc "));
...
|
JDOM
import org.jdom.*;
...
Element root = new
Element("linux-config");
// Wurzelelement erzeugen
Document doc = new
Document(root);
// neues Dok. benötigt nur Wurzel
root //
Dokumentstruktur erzeugen
.addContent(new Element("window-manager")
.addAttribute("default","true")
.addContent(new Element("name")
.setText("Enlightenment")))
.addContent(new Comment(" etc "));
...
|
Fazit
Hier
kann man sicherlich geteilter Meinung sein, ob die direkte Instanzierung
von Objekten die gute Lesbarkeit der Quellen fördert. Ein bedeutenderer
Unterschied, der hier sichtbar wird, ist die Behandlung des Textinhalts von
Elementen. Während das DOM diesen Textinhalt als echte Kindknoten eines
Elements betrachtet, behandelt JDOM diesen Text als Eigenschaft eines Elements.
Dies wird im folgenden Abschnitt noch deutlicher.
Situation
Natürlich besteht eine der Hauptaufgaben im Umgang mit XML darin, die im
Dokument enthaltenen Informationen zu extrahieren und weiterzuverwenden.
<league>
<team>
<name>Real Madrid</name>
<points>23</points>
<goals own="36"
against="11"/>
</team>
</league> |
Die Aufgabe der folgenden Programmfragmente besteht nun darin den
Mannschaftsnamen, die Punkte und die Tordifferenz in geeigneten Variablen zu
speichern. Hierzu nehmen wir ferner an, dass die Variable root das
Wurzelelement des Dokuments (<league>) enthält.
DOM
import
org.w3c.dom.*;...
try {
Element t = (Element)
root.getElementsByTagName("team").item(0);
// Name der Mannschaft als String speichern
Node n = t.getElementsByTagName("name").item(0);
String name =
n.getFirstChild().getNodeValue();
// Anzahl der Punkte als int speichern
Node p =
t.getElementsByTagName("points").item(0);
int pts = Integer.parseInt(p.getFirstChild().getNodeValue());
// Tordifferenz als int speichern
Element g = (Element)
t.getElementsByTagName("goals").item(0);
Attr own = g.getAttributeNode("own");
Attr ags = g.getAttributeNode("against");
int diff = Integer.parseInt(own.getValue())
-
Integer.parseInt(ags.getValue());
}
catch (Exception e) {
// Ausnahmebehandlung hier nur rudimentär
...
}
...
|
JDOM
import org.jdom.*;
...
try {
Element t = root.getChild("team");
// Name der Mannschaft
als String speichern
String name =
t.getChild("name").getText();
// Anzahl der Punkte
als int speichern
int pts = Integer.parseInt(t.getChild("points").getText());
// Tordifferenz als int speichern
int diff = t.getChild("goals").getAttribute("own").getIntValue()
-
t.getChild("goals").getAttribute("against").getIntValue();
}
catch (Exception e) {
// Ausnahmebehandlung hier nur rudimentär
...
}
...
|
Fazit
Spätestens an dieser Stelle wird der Mehraufwand, der durch die Verwendung
von DOM notwendig wird beachtlich. So gibt es zum Beispiel keine Möglichkeit
eine Referenz auf das erste Kindelement eines Knotens mit gegebenem Namen zu
erhalten, ohne zuvor eine Liste aller dieser Kindelemente zu erzeugen. Außerdem
wirkt sich auch hier der Unterschied bei der Handhabung des Textinhalts von
Elementen bei den beiden Werkzeugen zum Nachteil des DOM aus. Auch die
Bereitstellung von einigen Bequemlichkeitsmethoden bei JDOM, gerade bei der Bearbeitung
von Attributen, hilft dem Programmierer bei häufigen Aufgaben.
Situation
Zuweilen steht man vor der Aufgabe, dass die Struktur des Dokumentenbaums
verändert werden muss. Neue Elemente werden eingefügt oder bestimmte Attribute
entfernt. In den folgenden Programmfragmenten werden die Kindelemente eines
bestimmten Elements nach einem bestimmten Kriterium sortiert.
<league>
<team>
<name>Real Madrid</name>
<points>4</points>
<goals own="3"
against="2"/>
</team>
<team>
<name>Bayern München</name>
<points>9</points>
<goals own="5"
against="1"/>
</team>
<team>
<name>Dynamo Kiew</name>
<points>0</points>
<goals own="2"
against="6"/>
</team>
<team>
<name>Lazio Rom</name>
<points>4</points>
<goals own="3"
against="4"/>
</team>
</league> |
DOM
import
org.w3c.dom.*;...
NodeList teams = root.getElementsByTagName("team");
// die Elemente mit "Selection-Sort" sortieren
for (int i=0; i<positions.getLength(); ++i) {
// die beste verbliebene Mannschaft suchen
Element first = (Element) positions.item(i);
Element max = first;
for (int j=i+1; j<positions.getLength(); ++j) {
Element cand = (Element) positions.item(j);
if (comparePositions(max, cand) > 0) max = cand;
}
// Elemente tauschen
if (first != max) {
Node n = root.removeChild(max);
root.insertBefore(n,first);
}
}
...
|
JDOM
import java.util.*;
import org.jdom.*;
...
List teams = root.getChildren("team");
// Liste aller Mannschaften aufbauen
// unter Verwendung unseres konkreten Comparators
sortieren lassen
Collections.sort(teams, new
LigaComparator());
root.setChildren(teams); // sortierte Liste als
Kinder der Wurzel einsetzen
...
|
Fazit
Dieses Beispiel zeigt ganz deutlich, wie sich die Verwendung der
Standardkollektionen durch JDOM sehr positiv auf Kriterien wie Flexibilität,
Performanz, Programmieraufwand, Sicherheit, Lesbarkeit, Motivation, etc.
auswirkt.
Situation
Nach der Erzeugung oder Verarbeitung eines Dokuments, soll dieses wohl meist
als XML-Dokument in einer bestimmten Datei gespeichert werden.
Dies ermöglicht es in einer späteren Sitzung die Daten erneut einzulesen und
zu bearbeiten.
DOM
import java.io.*;
import
org.w3c.dom.*;
import
org.apache.xml.serialize.XMLSerializer;...
try {
FileOutputStream out = new
FileOutputStream(args[0]);
XMLSerializer serializer = new
XMLSerializer(out,null);
serializer.serialize(root);
out.flush();
out.close();
}
catch (IOException e) {
...
}
...
|
JDOM
import java.io.*;
import org.jdom.*;
import org.jdom.output.XMLOutputter;
...
try {
FileOutputStream out = new
FileOutputStream(args[0]);
XMLOutputter serializer = new
XMLOutputter();
serializer.output(doc,out);
out.flush();
out.close();
}
catch (IOException e) {
...
}
...
|
Fazit
Die Lösung des Problems ist in beiden Fällen unkompliziert und sehr
ähnlich. Im übrigen gilt hier das gleiche wie für das Einlesen eines
Dokuments: es ist unbedingt zu beachten, dass man sich bei der Verwendung
von DOM auf eine bestimmte Implementierung (hier: Xerces) festlegen muss, um das
Dokument zu Serialisieren, da das W3C in dieser Hinsicht keine Standardisierung
vorgenommen hat.
An dieser Stelle folgen noch zwei eigene Programme im vollen Quelltext, aus
denen die zuvor behandelten Problemfälle zum großen Teil entnommen sind. Da die
Programme kommentiert sind, wird hier auf eine ausführliche
Beschreibung verzichtet. Es ist wichtig, dass sich sowohl zum Kompilieren, als
auch zur Laufzeit, die notwendigen Pakete im aktuellen
Klassenpfad befinden.
Theatre
Beschreibung:
Dieses Programm gibt für ein Theaterstück eine Liste der Szenen aus, in denen
eine bestimmte Figur auftritt.
Dieses ist ein Beispiel für eine Aufgabe, die sich auch mit SAX lösen
lässt, da ein sequentieller, nur-lesender Zugriff auf die Daten ausreichend ist.
Die Verwendung von SAX ist sowohl im Hinblick auf die
Speicher-, als auch auf die Laufzeiteffizienz optimal, und sollte wann immer
möglich erfolgen.
Beispielaufruf:
javac Theatre1.java
java Theatre1 rich_iii.xml GLOUCESTER
ACT I - SCENE I. London. A street.
ACT I - SCENE II. The same. Another street.
ACT I - SCENE III. The palace.
ACT II - SCENE I. London. The palace.
ACT II - SCENE II. The palace.
ACT III - SCENE I. London. A street.
ACT III - SCENE IV. The Tower of London.
ACT III - SCENE V. The Tower-walls.
ACT III - SCENE VII. Baynard's Castle.
Links:
Das Programm unter Verwendung von...
Zwei Theaterstücke: rich_iii.xml two_gent.xml
League
Beschreibung:
Dieses Programm liest entweder eine Liste von Mannschaften von der
Standardeingabe, oder einen existierenden Tabellenstand aus einem XML-Dokument
ein. Danach wird für jede Mannschaft ein Ergebnis eingelesen, um dann einen
neuen Tabellenstand zu berechnen.
Links:
Das Programm unter Verwendung von...
[ DOM &
JDOM ] ... [ Beispiele ] ... [ Fazit ] ...
|
| |
 |
 |
|
Microsoft SharePoint-Technologien - Portal-Lösungen mit Windows SharePoint Services und SharePoint Portal Server 2003, mit CD-ROM (Gebundene Ausgabe)
von Ulrich B. Boddenberg
| |
|
| Siehe auch: | |
|
 |
|
Microsoft Windows SharePoint Services. Das offizielle Trainingsbuch
| | Konzepte und Lösungen für Microsoft-Netzwerke. Exchange, SharePoint, LCS, MOM, SMS, ISA, VMWare, Citrix, Storage, iSCSI, SAN, NAS, Backup, Veritas von Ulrich B. Boddenberg | | Microsoft Office InfoPath 2003. Das Handbuch. von Egbert Jeschke | | Microsoft SharePoint-Technologien. Planung, Design und Implementierung von Windows SharePoint Services 2003 von Kevin Laahs | |
|
|