Wie kann man in Java auf XML-Dokumente zugreifen?
Als Beispiel verwenden wir eine einfache XML-Datei:
<?xml version="1.0" encoding="UTF-8"?> <Adresse> <Nachname>Meier</Nachname> <Vorname>Willi</Vorname> <Strasse> <Name>Schlossallee</Name> <Nr>34</Nr> </Strasse> <Ort name="Hamburg" plz="20001"/> </Adresse>
Zunächst muss mit Hilfe der Klasse SAXBuilder ein
JDOM-Dokument erzeugt werden. Durch ein XMLOutputter-Objekt
kann dies schließlich als Byte-Strom in vielfältig
formatierter Weise ausgegeben werden. Hierzu dient die Klasse Format.
Ein Konstruktor ohne Parameterangabe entspricht der
Übergabe von Format.getRawFormat()
.
Die
Methode output()
sorgt für die Ausgabe und
erhält als Parameter das Dokument und einen OutputStream
oder Writer
.
Mit Hilfe entsprechender
Methoden lässt sich jetzt problemlos auf das Wurzelelement,
Kindelemente, Attribute und Werte zugreifen.
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
class JDOMLesen {
public static void main(String[] args) {
Document doc = null;
File f = new File("xml_file.xml");
try {
// Das Dokument erstellen
SAXBuilder builder = new SAXBuilder();
doc = builder.build(f);
XMLOutputter fmt = new XMLOutputter();
// komplettes Dokument ausgeben
fmt.output(doc, System.out);
// Wurzelelement ausgeben
Element element = doc.getRootElement();
System.out.println("\nWurzelelement: " + element);
// Wurzelelementnamen ausgeben
System.out.println("Wurzelelementname: " + element.getName());
// Eine Liste aller direkten Kindelemente eines Elementes erstellen
List alleKinder = (List) element.getChildren();
System.out.println("Erstes Kindelement: "
+ ((Element) alleKinder.get(0)).getName());
// Eine Liste aller direkten Kindelemente eines benannten
// Elementes erstellen
List benannteKinder = element.getChildren("Strasse");
// Das erste Kindelement ausgeben
System.out.println("benanntes Kindelement: "
+ ((Element) benannteKinder.get(0)).getName());
// Wert eines bestimmten Elementes ausgeben
Element kind = element.getChild("Nachname");
System.out.println("Nachname: " + kind.getValue());
// Attribut ausgeben
Element kind2 = element.getChild("Ort");
System.out.println("Ortsname: " + kind2.getAttributeValue("name"));
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Das "Simple API for XML Parsing (SAX)" basiert auf
einem Ereignismodell und liest eine XML-Datei wie einen
Datenstrom.
Die Basis bildet ein Handler-Objekt, das durch
Erweitern der Klasse DefaultHandler erzeugt wird. Zur
Ausgabe werden üblicherweise fünf Methoden
überschrieben, die per default nichts unternehmen. Sie
dienen der Manipulation, des im jeweiligen Methodennamen
angesprochenen Dateibereiches.
Zur Demonstration der
Arbeitsweise werden an zwei Stellen "xxx", bzw.
"+++" eingefügt.
startDocument()
endDocument()
startElement()
endElement()
characters()
import java.io.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
public class SAXLesen extends DefaultHandler {
static final String neueZeile = System.getProperty("line.separator");
static private Writer out = null;
private StringBuffer textBuffer = null;
public static void main(String[] argv) {
// SAX-EventHandler erstellen
DefaultHandler handler = new SAXLesen();
// Inhalt mit dem Default-Parser parsen
SAXParser saxParser;
try {
saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(new File("xml_file.xml"), handler);
} catch (ParserConfigurationException pe) {
pe.printStackTrace();
} catch (SAXException se) {
se.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
}
}
// SAX DefaultHandler Methoden
public void startDocument() throws SAXException {
ausgabe("auf geht's!" + neueZeile);
}
public void endDocument() throws SAXException {
ausgabe("finito!" + neueZeile);
}
// Starttag auslesen
public void startElement(String namespaceURI, String localName,
String qName, Attributes attrs) throws SAXException {
textPuffer();
String eName = ("".equals(localName)) ? qName : localName;
ausgabe("<" + eName);
// Erfassen der Attribute in den Starttags
if (attrs != null) {
for (int i = 0; i < attrs.getLength(); i++) {
String aName = attrs.getLocalName(i);
if ("".equals(aName))
aName = attrs.getQName(i);
ausgabe(" " + aName + "=\"" + attrs.getValue(i) + "\"");
}
}
ausgabe(">");
}
// Schlusstags auslesen
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
textPuffer();
String eName = ("".equals(localName)) ? qName : localName;
ausgabe("</" + eName + ">");
}
// Erzeugt einen String aus den Char-Arrays und liest
// diesen in einen StringBuffer ein
public void characters(char[] buf, int offset, int len) throws SAXException {
String s = new String(buf, offset, len);
if (textBuffer == null)
textBuffer = new StringBuffer(s);
else
textBuffer.append(s);
}
/** ************** Hilfsmethoden ******************* */
// Wandelt den StringBuffer in einen String und
// übergibt ihn zur Ausgabe
// "xxx" verdeutlicht die Arbeitsweise
private void textPuffer() throws SAXException {
if (textBuffer == null)
return;
ausgabe("xxx" + textBuffer.toString());
textBuffer = null;
}
// Ausgabe des Strings
// "+++" verdeutlicht die Arbeitsweise
private void ausgabe(String s) throws SAXException {
try {
if (out == null)
out = new OutputStreamWriter(System.out, "UTF8");
out.write(s + "+++");
out.flush();
} catch (IOException ex) {
throw new SAXException("Ein-/Ausgabefehler", ex);
}
}
}
1) JDOM muss vor der Benutzung von der Webseite des JDOM-Projektes heruntergeladen und in den Classpath eingebunden werden.