Berner Fachhochschule
Software Schule Schweiz
JDOM
http://www.jdom.org/
Beatrice Amrhein
Oktober 06
1 Motivation
JDOM ist ein Open Source, Baumbasiertes, Java API zum Parsen, Erzeugen, Verarbeiten und Speichern von
XML Dokumenten.
JDOM ist in und für Java entwickelt und benutzt die üblichen Java Konventionen und deren Class Library.
So werden zum Beispiel die Kinder eines Elementes in einer Java-Liste gespeichert.
JDOM implementiert keinen eigenen Parser, sondern benutzt einen SAX Parser zum Einlesen und Aufbauen
von JDOM Modellen.
Ein einmal (ins Memory) eingelesenes Dokument (egal ob von einem File eingelesen oder vom Java Programm
neu erzeugt) ist beliebig veränderbar. Der gesamte Dokument Baum kann gelesen und überschrieben werden.
Ist die Arbeit am Dokument beendet ist das Schreiben der Daten in ein XML Dokument mit JDOM sehr einfach.
1.1 Vergleich von DOM zu JDOM
Das org.w3c.dom Java Package stellt Interfaces für das Document Object Model (DOM, Document Object
Model, W3C Recommendation 07 April 2004) zur Verfügung. Diese sind aber nicht sehr komfortabel zu
benutzen:
Die wichtigsten Interfaces von org.w3c.dom
Attr
Das Attr Interface für die Attribute in einem Element Objekt.
CDATASection
Das Interface für CDATA Abschnitte.
CharacterData
Das Interface für Text Daten im DOM.
Comment
Abgeleitet von CharacterData für Kommentare innerhalb <!--' und '-->'.
Document
Das Document Interface als Container für den ganzen XML Baum.
Element
Das Element Interface für XML Elemente.
Node
Das Node Interface ist der wichtigste Datentyp für das Document Object Model.
Alle XML Knoten (Elemente, Text-Knoten, ...) sind in erster Linie vom Typ Node.
NodeList
Das NodeList Interface dient als Abstraktion für eine Liste von Notes, ohne zu definieren,
wie diese Liste implementiert warden soll.
Text
Das Text Interface ist abgeleitet von CharacterData und dient zum Bearbeiten von Text
in Elementen oder Attributen.
Das Node Interface bietet die Basis zum Aufbau eines DOM Baumes:
{
...
Node thisNameNode = thisCoffeeNode.getFirstChild();
String data = thisNameNode.getFirstChild().getNodeValue();
Node newHelloNode = document.createElement("Hello");
Text tnNode = document.createTextNode("World");
newNameNode.appendChild(tnNode);
...
}
JDom ist kein Wrapper für DOM. Es bietet vielmehr je eine Klasse für alle XML Knoten (Attribute, Kommentare,
Elemente, Text-Knoten, ...) und Methoden zum Verarbeiten derselben:
2
Die wichtigsten Klassen von jdom
Attribute
Ein XML Attribute.
CDATA
Eine XML CDATA Abschnitt.
Comment
Ein XML Kommentar.
Content
Basis Klasse für JDOM alle Objekte.
DefaultJDOMFactory
Erzeugt Standard JDOM Klassen (Element, Document, Comment, etc).
DocType
Eine XML DOCTYPE Deklaration.
Document
Ein XML Dokument.
Element
Ein XML Element.
EntityRef
Eine XML Entity Referenz.
Text
Text basierter XML Inhalt.
Das Arbeiten mit JDom ist viel natürlicher und direkter als über das DOM Interface:
while (i.hasNext())
{
Element person = (Element) i.next();
Element name = person.getChild("name");
Attribute date = person.getAttribute(“date“);
...
}
3
2 Das JDom Package
Die JDOM Packages
org.jdom
org.jdom.adapters
org.jdom.filter
org.jdom.input
org.jdom.output
org.jdom.transform
org.jdom.xpath
2.1 Die wichtigsten Klassen von JDom
Die Klasse
Attribute
CDATA
Comment
DocType
Docment
Element
Text
EntityRef
Namespace
Verifier
Zum Bearbeiten von
Æ
Æ
Æ
Æ
Æ
Æ
Æ
XML Attributen
CDATA Strings
Kommentaren
XML DOCTYPE Deklaration.
XML Dokumenten
XML Element-Knoten
XML Text Knoten
definiert eine XML Entity Reference
definiert einen XML Namespace
Testen von Wohlgeformtheit und
Gültigkeit
Die Document Klasse
Erzeugen eines neuen JDom-Documents mit Root
Element root.
new Document(Element root)
Weitere Methoden
get/setDocType()
get/setRootElement ()
liest / (er-) setzt den DTD
liest / (er-) setzt das RootElement
Die Document Klasse enthält die
Methoden zum Lesen und
Verarbeiten der Dokument-Struktur:
Document addContent(Comment c)
java.util.List getContent()
java.util.List getContent(Filter filter)
Element getRootElement()
boolean hasRootElement()
boolean
removeContent(Comment c)
Document setContent(java.util.List c)
...
4
Die wichtigsten Befehle der Klasse
Element:
Die Klasse Element
new Element( String name )
Erzeugen eines neuen Elements:
Element getChild (java.lang.String name, Namespace ns)
java.util.List getChildren()
das erste Kind (mit diesem Namen)
die Liste aller Kinder
Element setContent (Content child)
(er-) setze Element Inhalt
Element addContent(int index, Content child)
ergänze den Inhalt des Elements.
Element set-/getAttribute( ... )
Die Klasse Attribute
Erzeugen eines neuen Attributes:
new Attribute( String name, String value )
Weitere Methoden
set/getValue()
lesen / ersetzen des Attribut-Werts
set/getName() lesen / ersetzen des Attribut-Namens
String getName()
Attribute getAttribute( . . . )
Element setAttribute( . . . )
List getAttributes()
String getAttributeValue( . . .)
Element getParent()
String getText()
Element setText(String text)
String getTextTrim()
boolean hasChildren()
Element getChild( . . . )
List getChildren( . . . )
String getChildText( . . . )
String getChildTextTrim( . . . )
Element addContent( . . . )
Element setContent( . . . )
Die wichtigsten Methoden der Klasse
Attribute:
String getName()
Attribute setName(String name)
Attribute setValue(String value)
String getValue()
int getIntValue()
boolean getBooleanValue()
float getFloatValue()
...
Namespace getNamespace()
Element getParent()
...
5
3 Beispiele
3.1 Erzeugen eines XML Dokuments
Gesucht ist ein JDOM Dokument, welches (zum Beispiel beim Schreiben in ein in ein File mit dem XMLOutputter) genau diese XML Struktur erzeugt.
<?xml version="1.0"?>
<myRoot>Hello World!</myRoot>
Das entsprechende JDOM Document kann auf die folgende Art erzeugt werden:
Element root = new Element("myRoot");
root.setText("Hello World!");
Document doc = new Document(root);
Falls zusätzlich im Root Element ein Attribut eingefügt werden soll
<?xml version="1.0"?>
<myRoot date="5.9.02">
Hello World!
</myRoot>
muss das Document wie folgt erweitert werden
Element root = new Element("myRoot");
root.setText("Hello World!");
root.setAttribute("date", "5.9.02");
Document doc = new Document(root);
Weitere Elemente können dann mit addContent() eingefügt werden:
Element root = new Element("myRoot");
Element ele1 = new Element("myElem");
Element ele2 = new Element("myElem");
ele1.setText("Hello!");
ele2.setText("World!");
root.addContent(ele1);
root.addContent(ele2);
root.setAttribute("date", "5.9.02");
Document doc = new Document(root);
<?xml version="1.0"?>
<myRoot date="5.9.02">
<myElem>Hello</myElem>
<myElem>World!</myElem>
</myRoot>
6
3.2 Schreiben des JDom Baumes in ein XML File
Das so erzeugte Document kann nachher sehr einfach schön formatiert in ein File geschrieben werden.
FileOutputStream out = new FileOutputStream(file);
// use pretty format
XMLOutputter serializer =
new XMLOutputter(Format.getPrettyFormat());
serializer.output(doc, out);
3.3 Einlesen / Bearbeiten von XML Files
Im umgekehrten Fall, also wenn bereits ein XML Dokument vorliegt, kann dieses mit Hilfe des SAX Builders in
ein JDom Document eingefüllt werden:
1. Erzeugen eines SAXBuilder
2. build() aufrufen, um ein Document Object zu
erzeugen
3. Bearbeiten des Dokuments mit den Methoden der
Klassen Document, Element class, Attribute, ...
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(inFile);
Element root = doc.getRootElement();
3.4 Beispiel: Validieren eines XML Dokumentes mit JDOM
import org.jdom.*; import org.jdom.input.*; import java.io.*;
public class JDOMValidator {
public static void main(String[] args) {
if (args.length == 0) {
// command line should offer URIs or file names
System.out.println("Usage: java JDOMValidator URL");
return;
}
SAXBuilder builder = new SAXBuilder(true);
// Turn on validation
try {
Document doc = builder.build(args[0]);.
System.out.println(args[0] + " is valid.");
// No error
}
catch (JDOMException e) {
// indicates a well-formedness or validity error
System.out.println(args[0] + " is not valid. \n" + e.getMessage());
}
catch (Exception e) {
System.out.println("Could not check " + args[0] + ": “ + e.getMessage());
}
}
}
7
3.5 Konvertieren von DOM Dokumenten nach JDOM
Das package org.jdom.input besitzt eine Klasse DomBuilder, welcher zum Parsen eines DOM Dokuments
verwendet werden kann.
// @param domDoc the DOM document
public org.jdom.Document convert(org.w3c.dom.Document domDoc)
throws JDOMException, IOException
{
// Create new DOMBuilder, using default parser
org.jdom.input.DOMBuilder builder = new org.jdom.input.DOMBuilder();
}
// read dom document into jdom document
org.jdom.Document jdomDoc = builder.build(domDoc);
return jdomDoc;
3.6 Verwenden von XPath in JDOM
Mit Hilfe des jdom.xpath packages können wir auch die Methode getElementByID von DOM nachbauen.
xpath.selectSingleNode gibt uns das erste (und falls der Attribut-Wert eine ID ist das einzige) Element unter dem
gesuchten Pfad zurück.
Der Pfad, welchen wir hier benutzen, lautet:
path[attrName=’attrValue]
was so viel bedeutet wie: alle Elemente unter dem Pfad path, welche ein Attribut namens attrName mit dem
Wert attrValue besitzen.
/**
* Gets the (first) element found at path 'path' with a given attribute value.
* @param path -- the search path.
* @param attrName -- the name of the attribute.
* @param attrValue -- the value of the attribute.
* @param context -- the element context (e.g. the root Element).
* @return the first element found with a given attribute value.
* @throws JDOMException
*/
private Element getElementByID(String path, String attrName,
String attrValue, Element context) throws JDOMException
{
String pathString = path + "[@" + attrName + "='" + attrValue + "']";
XPath xpath = XPath.newInstance(pathString);
return (Element) xpath.selectSingleNode(context);
}
8