Die W3C-Spezifikation des
Document Object Models
(abgekürzt als: DOM) definiert eine
Programmiersprachen-unabhängige und plattformneutrale Menge
abstrakter Schnittstellen, mit denen Programme und Skripte
lesend und schreibend auf gültige HTML-Dokumente und
wohlgeformte XML-Dokumente sowie eine Reihe weiterer Formate
zugreifen können.
HTML: Das Dokument kann weiterverarbeitet werden, das
Ergebnis dieser Verarbeitung kann direkt in die angezeigte
Seite eingebunden werden.
DOM versteht sich als Application Programming Interface (API) für beliebige XML-Dokumente (und damit auch XHTML-Dokumente). Es definiert die logische Struktur eines Dokumentes und die Art und Weise, wie auf diese Struktur zugegriffen und die Information verändert werden kann. Hierzu versammelt es auf Basis einer generischen Speicherrepräsentation für XML eine Menge von Operationen.
Programmierer können mit DOM Dokumente erstellen, entlang ihrer Struktur navigieren, Elemente und deren Inhalt hinzufügen, verändern oder löschen.
Als W3C-Spezifikation zielt DOM nicht auf eine spezielle
Programmierumgebung ab, sondern wurde vor dem
Hintergrund entworfen, für beliebige unterschiedlicher
Programmiersprachen einsetzbar zu sein.
Aus diesem Grund wurde die Spezifikation in einer
besonderen Sprache für Schnittstellen, der sogenannten
Interface Definition Language (IDL)
entworfen.
Es existiert eine Abbildung der IDL Spezifikation auf
die Programmiersprache Java.
<table>
<tbody>
<tr>
<td>Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr>
<td>Over the River, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
// access the tbody element from the table element var myTbodyElement = myTableElement.firstChild; // access its second tr element // The list of children starts at 0 (and not 1). var mySecondTrElement = myTbodyElement.childNodes[1]; // remove its first td element mySecondTrElement.removeChild(mySecondTrElement.firstChild); // change the text content of the remaining td element mySecondTrElement.firstChild.firstChild.data = "Peter";
DOM spezifizierte ursprünglich, wie JavaScript Skripte und Java-Programme über Web Browser hinweg portabel sein konnten. "Dynamisches HTML" war der direkte Vorgänger des DOM. Der Fokus lag damals stark auf Browsern. Im Rahmen der Weiterentwicklung hatte die SGML und schließlich die XML so starken Einfluß auf DOM, daß mittlerweile der Hauptfokus auf XML-Dokumenten liegt.
DOM bietet eine Menge von einzelner APIs, die zusammen die DOM API bilden. Jede dieser Spezifikationen definiert ein oder mehrere Module, von denen wiederum jedes mit ein oder mehr Feature-Namen assoziiert ist.
Die DOM Core spezifikation definiert beispielsweise zwei Module:
Core.
XML.
Die folgende Abbildung zeigt alle DOM Module mit ihren Feature-Namen, die in DOM spezifiziert sind:

DOM Level 2 erweitert die in Level 1 eingeführten Schnittstellen hinsichtlich der Erfordernisse des aktuellen XML-Standes um Namensräume und bietet einige neue Operationen, die seitens der Anwendergemeinde gefordert wurden. Die bisherigen Operationen existieren aus Kompatibilitätsgründen weiter, die Namespace-berücksichtigenden Pendants sind identisch benannt, jedoch um ein angehängtes NS erweitert.
DOM Level 3 komplettiert im Vergleich zu DOM Level 2 die Abbildung zwischen DOM und dem XML Information Set. Dies beinhaltet Unterstützung für XML Base, Unterstützung zur Auflösung von Namensraumpräfixen oder der Manipulation von ID Attributen, etc.
Eine Implementierung darf sich als konform zur DOM Level 3 Spezifikation bezeichnen, wenn sie das Core -Modul unterstützt.
Eine Implementierung darf sich als konform zu einem DOM Level 3 Modul bezeichnen, wenn sie alle zu diesem Modul definierten Schnittstellen unterstützt, sowie die damit verbundene Semantik.
Ob eine DOM-Implementierung ein einzelnes Modul
unterstützt, kann durch die Schnittstellenfunktion
hasFeature
der Schnittstelle
DOMImplementation
des Moduls
Core
ermittelt werden.
javax.xml.parsers
organisiert.
org.w3c.dom
import org.w3c.dom.DOMImplementation; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;
factory
-Instanz, die den Parser (ein Objekt der Klasse
DocumentBuilder
) liefert.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();hasFeature
ist abhängig von der konkreten Implementierung des
Parsers und wird auf der Schnittstelle
DOMImplementation
aufgerufen. Diese muß zunächst erzeugt werden.
DOMImplementation implementation = builder.getDOMImplementation();
String feature[] = {
"Core", "XML", "HTML", "XPath", "Validation",
"Events", "LS", "Views", "Traversal", "LS-Async",
"StyleSheets", "Range", "HTMLEvents", "MutationEvents",
"UIEvents", "CSS", "MutationNameEvents", "CSS2",
"KeyboardEvents", "TextEvents", "MouseEvents"
}; for (int i = 0; i < feature.length; i++) {
System.out.print(feature[i]);
if (!implementation.hasFeature(feature[i], "3.0")) {
System.out.println(" not supported");
} //if
else {
System.out.println(" supported");
} //else
} //forCore supported XML supported HTML not supported XPath not supported Validation not supported Events not supported LS supported Views not supported Traversal not supported LS-Async not supported StyleSheets not supported Range not supported HTMLEvents not supported MutationEvents not supported UIEvents not supported CSS not supported MutationNameEvents not supported CSS2 not supported KeyboardEvents not supported TextEvents not supported MouseEvents not supported
Die Schnittstelle Document stellt eine spezialisierte
Schnittstelle von
Node
dar. Sie stellt den Einstieg in ein XML-Dokument dar und
wird deshalb zuerst behandelt.
Diese Schnittstelle steht für das gesamte XML oder XHTML-Dokument. Sie bildet die Wurzel des Dokumentbaumes und bietet den ersten Einstiegspunkt, um auf die Daten des Dokuments zuzugreifen.
Weil es außerhalb des Kontexts eines Dokuments keine
Textknoten, Kommentare, Processing Instructions, etc.
geben kann, enthält die Schnittstelle
Document
auch die Fabrikmethoden zur Erzeugung dieser Objekte.
DOM definiert folgende vier Datentypen
DOMString
:
DOMString
werden Zeichen als Sequenz von 16-Bit Einheiten
codiert. Die Codierung ist UTF-16.
DOMString
abgebildet werden.
DOMString
durch den Datentyp
String
abgebildet.
DOMTimeStamp
:
DOMTimeStamp
werden absolute und relative Zeiten abgespeichert.
Die Einheit von
DOMTimeStamp
sind Millisekunden.
DOMTimeStamp
durch den Datentyp
long
abgebildet.
DOMUserData
:
DOMUserData
werden Applikationsdaten abgelegt.
DOMUserData
mit dem Datentyp
Object
abgebildet.
DOMObject
:
DOMObject
repräsentiert ein Objekt, es stellt eine
Objektreferenz dar.
DOMObject
mit dem Datentyp
Object
abgebildet.
Die Schnittstelle besitzt folgende Eigenschaften
// Modified in DOM Level 3:
readonly attribute DocumentType doctype;
readonly attribute DOMImplementation implementation;
readonly attribute Element documentElement;
// Introduced in DOM Level 3:
readonly attribute DOMString inputEncoding;
readonly attribute DOMString xmlEncoding;
readonly attribute DOMConfiguration domConfig;
attribute boolean xmlStandalone;
// raises(DOMException) on setting
attribute DOMString xmlVersion;
// raises(DOMException) on setting
attribute boolean strictErrorChecking;
attribute DOMString documentURI;Einige wenige Attribute der Schnittstelle erlauben einfachen und schnellen Zugriff auf Kindelemente, ohne daß dorthin navigiert werden muss:
doctype
documentElement
Bedeutung DOM-sezifischer Attribute:
domConfig
:
Document.normalizeDocument()
verwendet wird.
implementation
:
DOMImplementation
Objekt, das das Dokument bearbeitet.
inputEncoding
:
null
.
strictErrorChecking
:
true
.
Abbildung nach Java:
| DOM Attribut | Java Methode(n) |
|---|---|
doctype
|
DocumentType getDoctype()
|
implementation
|
DOMImplementation getImplementation()
|
documentElement
|
Element getDocumentElement()
|
inputEncoding
|
String getInputEncoding()
|
xmlEncoding
|
String getXmlEncoding()
|
xmlStandalone
|
boolean getXmlStandalone()
,
void setXmlStandalone(boolean
xmlStandalone)
|
xmlVersion
|
String getXmlVersion()
,
void setXmlVersion(String xmlVersion)
|
strictErrorChecking
|
boolean getStrictErrorChecking()
,
void setStrictErrorChecking(boolean
strictErrorChecking)
|
documentURI
|
String getDocumentURI()
,
void setDocumentURI(String documentURI
|
Folgende Operationen sind für die Schnittstelle
Document
definiert:
Element createElement(in DOMString tagName)
raises(DOMException);
DocumentFragment createDocumentFragment();
Text createTextNode(in DOMString data);
Comment createComment(in DOMString data);
CDATASection createCDATASection(in DOMString data)
raises(DOMException);
ProcessingInstruction createProcessingInstruction(in DOMString target,
in DOMString data)
raises(DOMException);
Attr createAttribute(in DOMString name)
raises(DOMException);
EntityReference createEntityReference(in DOMString name)
raises(DOMException);
NodeList getElementsByTagName(in DOMString tagname);
// Introduced in DOM Level 2:
Node importNode(in Node importedNode,
in boolean deep)
raises(DOMException);
Element createElementNS(in DOMString namespaceURI,
in DOMString qualifiedName)
Attr createAttributeNS(in DOMString namespaceURI,
in DOMString qualifiedName)
raises(DOMException);
NodeList getElementsByTagNameNS(in DOMString namespaceURI,
in DOMString localName);
Element getElementById(in DOMString elementId);
// Introduced in DOM Level 3:
Node adoptNode(in Node source)
raises(DOMException);
void normalizeDocument();
Node renameNode(in Node n,
in DOMString namespaceURI,
in DOMString qualifiedName)
raises(DOMException);adoptNode
Adoptierteinen Knoten aus einem anderen Dokument. Wenn die Operation unterstützt wird, ändert sich die Eigenschaft
ownerDocument
des Knotens, seiner Kinder und aller evtl.
vorhandenen Attributknoten. Der Knoten wird aus der
Kindknoten-Liste seines ursprünglichen
Elternelements entfernt. Auf diese Weise kann ein
Teilbaum sehr effektiv von einem Dokument zum
anderen bewegt werden. Ist diese Operation nicht
unterstützt, sollte stattdessen
importNode
verwendet werden.
importNode
bewegt keine Teilbäume durch Umkopieren, sondern
erzeugt eine Kopie des Quellknotens. Das
Quelldokument wird dabei nicht verändert. Ergebnis
der Operation ist ein neu erzeugter Knoten (die
Kopie), der noch an kein Elternelement angehängt
ist. Beim Kopiervorgabg werden auch sämtliche
Attributwerte inkl. der Namensraumattribute kopiert.
createElement
,
createAttribute
,
createTextNode
,
createComment
,
createCDATASection
,
createProcessingInstruction
,
createEntityReference
und
createDocumentFragment
dienen zum Erzeugen neuer Knoten des jeweiligen
Knotentyps.
createElementNS
und
createAttributeNS
erzeugen Element- bzw. Attributknoten mit
entsprechenden Namensrauminformationen.
getElementsByTagNameNS
gibt eine Liste von Knoten zurück, die den
angegebenen lokalen Namen besitzen und sich im
angegebenen Namensraum befinden.
getElementById
gibt das Element zurück, das ein ID-Attribut
enthält, dessen Wert dem angegebenen Wert
entspricht.
normalizeDocument
Normalisiertdas Dokument. Dies betrifft insbesondere Textknoten, die wie in der Methode
Node.normalize()
normalisiert werden (z.B. Entfernen leerer
Textknoten). Welche weiteren
Normalisierungsmöglichkeiten auf das Dokument
angewendet werden sollen, wird in der
DOMConfiguration
festgelegt.
renameNode
Dient zur Umbenennung eines Element- oder
Attributknotens. Optimalerweise wird einfach der
Name des betreffenden Knotens verändert, andernfalls
ein neuer Knoten mit einem entsprechenden Namen
erzeugt und der vorhandene Knoten durch den neuen
ersetzt.
Abbildung in Java
| DOM Methode | Java Methode(n) |
|---|---|
createElement(in DOMString tagName)
|
Element createElement(String tagName)
|
createDocumentFragment()
|
DocumentFragment
createDocumentFragment()
|
createTextNode(in DOMString data)
|
Text createTextNode(String data)
|
createComment(in DOMString data)
|
Comment createComment(String data)
|
createCDATASection(in DOMString data)
|
|
createProcessingInstruction(in DOMString
target, in DOMString data)
|
CDATASection createCDATASection(String
data)
|
createAttribute(in DOMString name)
|
Attr createAttribute(String name)
|
createEntityReference(in DOMString name)
|
EntityReference
createEntityReference(String name)
|
getElementsByTagName(in DOMString
tagname)
|
NodeList getElementsByTagName(String
tagname)
|
importNode(in Node importedNode, in
boolean deep)
|
Node importNode(Node importedNode,
boolean deep)
|
createElementNS(in DOMString
namespaceURI, in DOMString
qualifiedName)
|
Element createElementNS(String
namespaceURI, String qualifiedName)
|
createAttributeNS(in DOMString
namespaceURI, in DOMString
qualifiedName)
|
Attr createAttributeNS(String
namespaceURI, String qualifiedName)
|
getElementsByTagNameNS(in DOMString
namespaceURI, in DOMString localName)
|
NodeList getElementsByTagNameNS(String
namespaceURI, String localName)
|
getElementById(in DOMString elementId)
|
Element getElementById(String elementId)
|
adoptNode(in Node source)
|
Node adoptNode(Node source)
|
normalizeDocument()
|
void normalizeDocument()
|
renameNode(in Node n, in DOMString
namespaceURI, in DOMString
qualifiedName)
|
Node renameNode(Node n, String
namespaceURI, String qualifiedName)
|
Es ist festzustellen, daß die Abbildung der DOM Attribute und Operationen in die Programmiersprache Java sich sehr übersichtlich gestaltet.
In diesem Codebeispiel soll eine DOM-basierte Speicherstruktur mit SUNs JDK erzeugt werden.
parse
erzeugt ein Document-Objekt gemäß der W3C
Spezifikation.
Document document = builder.parse(args[0]);
org.w3c.dom
zusammengefaßt.
import org.w3c.dom.Document; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class DOMExample3 {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(args[0]);
} //main()
} //class DOMExample3documentElement
bereitgestellt. Es liefert ein Objekt des Typs
Element
.
Die Schnittstelle
Node
ist der wichtigste Datentyp für das gesamte DOM. Sie
stellt einen einzelnen Knoten im gesamten Dokumentbaum
dar.
Die Schnittstelle konzentriert alle gemeinsamen Anteile der verschiedenen Knoten eines XML-Baumes. Hierzu gehören:
Alle Objekte, die die Schnittstelle
Node
implementieren, stellen Methoden zur Verfügung, um mit
Kindknoten umzugehen. Gleichzeitig verfügen jedoch nicht
alle dieser Objekte über Kindknoten (z.B. Textknoten,
diese haben keine Kindknoten).
In der Schnittstelle sind verschiedene Konstanten definiert, die dazu dienen, eine Typisierung für die verschiedenen Arten von Knoten zu realisieren. Ein Integer weist darauf hin, um welchen Knotentyp es sich handelt (die Zahlen bis 200 sind hierfür reserviert). Für jeden dieser Knotentypen existiert jeweils eine eigene DOM-Schnittstelle.
const unsigned short ELEMENT_NODE = 1; const unsigned short ATTRIBUTE_NODE = 2; const unsigned short TEXT_NODE = 3; const unsigned short CDATA_SECTION_NODE = 4; const unsigned short ENTITY_REFERENCE_NODE = 5; const unsigned short ENTITY_NODE = 6; const unsigned short PROCESSING_INSTRUCTION_NODE = 7; const unsigned short COMMENT_NODE = 8; const unsigned short DOCUMENT_NODE = 9; const unsigned short DOCUMENT_TYPE_NODE = 10; const unsigned short DOCUMENT_FRAGMENT_NODE = 11; const unsigned short NOTATION_NODE = 12;
Der Knotentyp eines jeden Knotens kann über das in DOM
spezifizierte Attribut
nodeType
abgefragt werden.
In Java ist dieses DOM-Attribut durch die Operation
getNodeType()
abgebildet.
Im vorgestellten Beispiel wird diese Operation auf verschiedenen Knotentypen aufgerufen:
Auszug aus dem Sourcecode: Aufruf der Operation auf Inhaltsknoten des Wurzelelementes
for (int i=0; i< childNodes.getLength(); i++) {
System.out.println("Child Node at position " + i + " has type " + childNodes.item(i).getNodeType() );
} Angewendet auf das folgendes XML-Dokument...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Vorlesung> <Pflichtfach/> <Hochschule>Fachhochschule Augsburg</Hochschule> <Studiengang semester="3">IAM</Studiengang> <Titel>XML</Titel> <Semester>WS 2008/2009</Semester> Montag, 08:00h - 09:30h <Praktikum>Seminar</Praktikum> </Vorlesung>
... ergibt sich folgende Ausgabe:
Document node is of type: 9 Root element is of type: 1 Root element has 13 child elements Child Node at position 0 has type 3 Child Node at position 1 has type 1 Child Node at position 2 has type 3 Child Node at position 3 has type 1 Child Node at position 4 has type 3 Child Node at position 5 has type 1 Child Node at position 6 has type 3 Child Node at position 7 has type 1 Child Node at position 8 has type 3 Child Node at position 9 has type 1 Child Node at position 10 has type 3 Child Node at position 11 has type 1 Child Node at position 12 has type 3
Die gefundenen Textknoten entsprechen dem textuellen
Inhalt in
Vorlesung
inkl. der Zeilenumbrüche.
Mit den Attributen
nodeName
,
nodeValue
und
attributes
stehen grundlegende Attribute zur Verfügung, die es
erlauben, einfach auf die Information der betreffenden
Knoten zuzugreifen, ohne daß auf die spezifische
Schnittstelle des jeweiligen Knotentyps direkt
zugegriffen werden muß.
Hinweis: die spezifischen Schnittstellen enthalten unter
Umständen zusätzliche Mechanismen, mit denen man sehr
einfach relevante Informationen erhalten oder setzen
kann.
readonly attribute DOMString nodeName;
attribute DOMString nodeValue;
// raises(DOMException) on setting
// raises(DOMException) on retrieval
readonly attribute NamedNodeMap attributes;Abbildung nach Java:
nodeName
bildet sich auf die Methode
String getNodeName()
ab.
nodeName
ist für alle Knotentypen verfügbar.
System.out.println("Root element of name " + theRootElement.getNodeName() + " is of type: " + theRootElement.getNodeType());nodeValue
bildet sich auf die Methode
String getNodeValue()
ab.
nodeValue
ist für Knoten des Typs
ATTRIBUTE_NODE
,
CDATA_SECTION_NODE
,
COMMENT_NODE
,
PROCESSING_INSTRUCTION_NODE
und
TEXT_NODE
gesetzt.
if (childNodes.item(i).getNodeType()==3) {
System.out.println("Text Node has Value: " + childNodes.item(i).getNodeValue() );
} else {attributes
bildet sich auf die Methode
NamedNodeMap getAttributes()
ab.
attributes
liefert erwartungsgemäß nur für Knoten des Typs
ELEMENT_NODE
, die auch Attribute besitzen, ein positives
Ergebnis, ansonsten
null
.
Das vorige Beispiel erweitert um Ausgaben zu
nodeName
und
nodeValue
liefert folgende Ausgabe:
Document node is of type: 9 Root element of name Vorlesung is of type: 1 Root element has 13 child elements Child Node at position 0 with name #text has type 3 Text Node has Value: Child Node at position 1 with name Pflichtfach has type 1 Child Node at position 2 with name #text has type 3 Text Node has Value: Child Node at position 3 with name Hochschule has type 1 Child Node at position 4 with name #text has type 3 Text Node has Value: Child Node at position 5 with name Studiengang has type 1 Child Node at position 6 with name #text has type 3 Text Node has Value: Child Node at position 7 with name Titel has type 1 Child Node at position 8 with name #text has type 3 Text Node has Value: Child Node at position 9 with name Semester has type 1 Child Node at position 10 with name #text has type 3 Text Node has Value: Montag, 08:00h - 09:30h Child Node at position 11 with name Praktikum has type 1 Child Node at position 12 with name #text has type 3 Text Node has Value:
Des weiteren versammelt die Schnittstelle
Node
folgende weiteren Attribute:
readonly attribute unsigned short nodeType;
readonly attribute Node parentNode;
readonly attribute NodeList childNodes;
readonly attribute Node firstChild;
readonly attribute Node lastChild;
readonly attribute Node previousSibling;
readonly attribute Node nextSibling;
// Modified in DOM Level 2:
readonly attribute Document ownerDocument;
// Introduced in DOM Level 2:
readonly attribute DOMString namespaceURI;
attribute DOMString prefix;
// raises(DOMException) on setting
readonly attribute DOMString localName;
// Introduced in DOM Level 3:
readonly attribute DOMString baseURI;
attribute DOMString textContent;
// raises(DOMException) on setting
// raises(DOMException) on retrievalAbbildung nach Java:
| DOM Attribut | Java Methode(n) |
|---|---|
nodeType
|
short getNodeType()
|
parentNode
|
Node getParentNode()
|
childNodes
|
NodeList getChildNodes()
|
firstChild
|
Node getFirstChild()
|
lastChild
|
Node getLastChild()
|
previousSibling
|
Node getPreviousSibling()
|
nextSibling
|
Node getNextSibling()
|
ownerDocument
|
Document getOwnerDocument()
|
namespaceURI
|
String getNamespaceURI()
|
prefix
|
String getPrefix()
|
localName
|
String getLocalName()
|
baseURI
|
String getBaseURI()
|
textContent
|
String getTextContent()
|
Die aufgeführten Operationen erlauben Veränderungen der
Knotenstruktur. So können etwa neue Knoten in eine
bestehendes DOM-Objektmodell eingefügt werden.
Darüberhinaus können existierende Knoten ersetzt,
gelöscht und kopiert werden. Die Schnittstelle
Node
wird von allen im folgenden diskutierten nach Knotentyp
spezialisierten Schnittstellen erweitert.
boolean hasChildNodes();
Node cloneNode(in boolean deep);
// Modified in DOM Level 3:
Node insertBefore(in Node newChild,
in Node refChild)
raises(DOMException);
Node replaceChild(in Node newChild,
in Node oldChild)
raises(DOMException);
Node removeChild(in Node oldChild)
raises(DOMException);
Node appendChild(in Node newChild)
raises(DOMException);
void normalize();
unsigned short compareDocumentPosition(in Node other)
raises(DOMException);
// Introduced in DOM Level 2:
boolean isSupported(in DOMString feature,
in DOMString version);
boolean hasAttributes();
// Introduced in DOM Level 3:
boolean isSameNode(in Node other);
DOMString lookupPrefix(in DOMString namespaceURI);
boolean isDefaultNamespace(in DOMString namespaceURI);
DOMString lookupNamespaceURI(in DOMString prefix);
boolean isEqualNode(in Node arg);
DOMObject getFeature(in DOMString feature,
in DOMString version);
DOMUserData setUserData(in DOMString key,
in DOMUserData data,
in UserDataHandler handler);
DOMUserData getUserData(in DOMString key);
Die Abbildung in Java wird ab hier nicht mehr explizit
aufgeführt. Für eine Übersicht der Java Schnittstellen
siehe
Java API Dokumentation
, Paket
org.w3c.dom
.
Die Schnittstelle
Element
entspricht einem Element eines XML- oder
HTML-Dokumentes. Da die Schnittstelle
Node
erweitert wird, können die dort definierte generischen
Attribute verwendet werden, um beispielsweise die Menge
von Attributen zu einem Element zu erhalten.
Des weiteren enthält die Schnittstelle eine Reihe von
Operationen zum Zugriff auf XML-Elemente.
Die Schnittstelle versammelt folgende Eigenschaften:
readonly attribute DOMString tagName; // Introduced in DOM Level 3: readonly attribute TypeInfo schemaTypeInfo;
schemaTypeInfo
:
tagName
:
Folgende Operationen sind für die Schnittstelle
Element
definiert:
DOMString getAttribute(in DOMString name);
Attr getAttributeNode(in DOMString name);
void setAttribute(in DOMString name,
in DOMString value)
raises(DOMException);
Attr setAttributeNode(in Attr newAttr)
raises(DOMException);
void removeAttribute(in DOMString name)
raises(DOMException);
Attr removeAttributeNode(in Attr oldAttr)
raises(DOMException);
NodeList getElementsByTagName(in DOMString name);
// Introduced in DOM Level 2:
DOMString getAttributeNS(in DOMString namespaceURI,
in DOMString localName)
raises(DOMException);
Attr getAttributeNodeNS(in DOMString namespaceURI,
in DOMString localName)
raises(DOMException);
void setAttributeNS(in DOMString namespaceURI,
in DOMString qualifiedName,
in DOMString value)
raises(DOMException);
Attr setAttributeNodeNS(in Attr newAttr)
raises(DOMException);
void removeAttributeNS(in DOMString namespaceURI,
in DOMString localName)
raises(DOMException);
boolean hasAttribute(in DOMString name);
boolean hasAttributeNS(in DOMString namespaceURI,
in DOMString localName)
raises(DOMException);
NodeList getElementsByTagNameNS(in DOMString namespaceURI,
in DOMString localName)
raises(DOMException);
// Introduced in DOM Level 3:
void setIdAttribute(in DOMString name,
in boolean isId)
raises(DOMException);
void setIdAttributeNS(in DOMString namespaceURI,
in DOMString localName,
in boolean isId)
raises(DOMException);
void setIdAttributeNode(in Attr idAttr,
in boolean isId)
raises(DOMException);getAttribute
und
getAttributeNode
.
Attr
erhalten wird, mit der anderen jedoch der
Attributwert.
ID
.
In diesem Beispiel soll der Einsatz der Operation
hasAttributes
gezeigt werden. Die Methode testet, ob für das gegebene
Element Attribute existieren.
Zunächst wird mit der Methode
getDocumentElement
auf das Wurzelelement des Dokuments zugegriffen. Diese
Methode entspricht keiner DOM-Operation, sondern dem
DOM-Attribut
documentElement
.
Grund: Java erlaubt in Schnittstellen keine änderbaren
Attribute. Daher stellt die DOM-Implementierung des JDK
für diese Attribute eigene Zugriffsmethoden zur
Verfügung.
Element theRootElement = document.getDocumentElement();
In einem weiteren Schritt wird mittels
getTagName()
der Name des Wurzelelements ermittelt. Diese
Java-Methode entspricht dem DOM-Attribut
tagName
.
System.out.println("root element's name: " + theRootElement.getTagName());
Mit der Methode
hasAttributes()
wird schließlich abgefragt, ob das Element Attribute
besitzt, und eine entsprechende Ausgabe erzeugt.
System.out.print("the element has");
if (!theRootElement.hasAttributes())
System.out.print(" no");
System.out.println(" attributes");Das gesamte Listing:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class DOMExample4 {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(args[0]);
Element theRootElement = document.getDocumentElement();
System.out.println("root element's name: " + theRootElement.getTagName());
System.out.print("the element has");
if (!theRootElement.hasAttributes())
System.out.print(" no");
System.out.println(" attributes");
} //main()
} //class DOMExample4Angewandt auf die XML-Datei der Projektverwaltung liefert das Programm die Ausgabe:
root element's name: ProjektVerwaltung the element has attributes
Mit DOM kann -- im Gegensatz zu SAX -- ein eingelesenes Dokument verändert werden. Das hier diskutierte Beispiel demonstriert dies.
Dem Wurzelelement eines Dokuments (das Objekt
theRootElement
vom Typ
Element
) soll ein Attribut (benannt mit
myFirstNewAttribute
) hinzugefügt und mit dem Wert
01
belegt werden.
Element theRootElement = document.getDocumentElement();
System.out.println("root element's name: " + theRootElement.getTagName());
theRootElement.setAttribute("myFirstNewAttribute", "01");
if (theRootElement.hasAttribute("myFirstNewAttribute")){
System.out.println("Setting of attribute 'myFirstNewAttribute' successful!");
System.out.println("Value of attribute: " + theRootElement.getAttribute("myFirstNewAttribute"));
} else {
System.out.println("Setting of attribute failed.");
}
Zudem soll ein neues Element
myNewElement
als Kindelement des Wurzelelements erzeugt werden.
Element aNewElement = document.createElement("myNewElement");
theRootElement.appendChild(aNewElement);
if (theRootElement.hasChildNodes()){
System.out.println("Appending successful - root node now has child elements.");
} else {
System.out.println("Appending of child element failed.");
}
Achtung:
Die Methode
createElement
ist für die Schnittstelle
document
definiert und muß auf dieser aufgerufen werden.
Das neu erzeugte Element muß mit
appendChild
(von der Schnittstelle
Element
) an das Wurzelelement angehängt werden.
Hinweis: In früheren JDK-Versionen konnte durch den
Aufruf der Methode
String.println
ein DOM-Baum in eine Zeichenkettenrepräsentation
serialisiert und über die Standardausgabe ausgegeben
werden. Dies ist inzwischen nicht mehr der Fall!
Angewendet auf eine sehr einfache
Eingabedatei
mit dem (einzigen) Element
empty
als Wurzelelement ergibt sich folgende Ausgabe:
root element's name: empty Setting of attribute 'myFirstNewAttribute' successful! Value of attribute: 01 Appending successful - root node now has child elements. [empty: null]
Die Schnittstelle
NodeList
definiert einen Container zur Aufnahme beliebiger
Objekte des Typs
Node
. Sie definiert das Attribut
length
, welches zu jedem Zeitpunkt die Anzahl der verwalteten
Elemente enthält. Der Zugriff auf die verwalteten Knoten
erfolgt indexsequentiell durch die Methode
item
.
interface NodeList {
Node item(in unsigned long index);
readonly attribute unsigned long length;
};Das Beispiel zeigt die Verwendung der Schnittstelle, um festzustellen, wie oft ein als Kommandozeilenparameter übergebener Elementname in einem Dokument auftritt.
Die Methode
getElementsByTagName
der Schnittstelle
Document
fügt während der Ausführung alle Auftreten von Elementen
mit dem gesuchten Namen in die Ergebnismenge ein.
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class DOMExample6 {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(args[0]);
Element theRootElement = document.getDocumentElement();
NodeList nodes = theRootElement.getElementsByTagName(args[1]);
System.out.println("document contains " + nodes.getLength() + " elements of type " + args[1]);
} //main()
} //class DOMExample6
Angewendet auf die XML-Datei der
erweiterte Projektverwaltung
ergibt die Suche nach Elementen mit dem Namen
Vorname
...
java DOMExample6 projektverwaltung-erweitert.xml Vorname
... folgende Ausgabe:
document contains 4 elements of type Vorname
In diesem Beispiel (aus der Praxis) soll eine
statistische Aussage getroffen werden:
Wie viele Fehlerspeicher sind für ein Steuergerät in
einer XML-Datei definiert?
Für die Definition von Diagnosedaten für Steuergeräte existiert ein XML-Standard namens ODX . In diesem XML-Vokabular werden sogenannte Fehlerspeicher und Diagnosejobs definiert.
Eine Fehlerspeicher wird in ODX durch ein Element mit
dem Namen
DTC
definiert. Möchte man wissen, wie viele Fehlerspeicher
definiert sind, so benötigt man die Anzahl der
DTC
-Elemente.
Diese werden analog zum vorherigen Beispiel durch die
Methode
getElementsByTagName
in einer Knotenliste gesammelt. Die Länge der
Knotenliste ergibt die Anzahl der enthaltenen
DTC
-Elemente.
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class countDTCs {
public static void main(String[] args) throws Exception {
int numDTCs = 0;
System.out.println("\nFiles to work on:" + args.length);
for (int i=0; i<args.length; i++){
File myFile = new File (args[i]);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(myFile);
Element theRootElement = document.getDocumentElement();
NodeList DTCNodeList = theRootElement.getElementsByTagName("DTC");
System.out.println("File " + myFile.getName() + " contains " + DTCNodeList.getLength() + " DTCs!");
numDTCs = numDTCs + DTCNodeList.getLength();
} // for
System.out.println("\nAll Files together contain " + numDTCs + " DTCs.");
} //main()
} //class countDTCsFiles to work on:20 File ECU0.odx-d contains 0 DTCs! File ECU1.odx-d contains 65 DTCs! File ECU2.odx-d contains 83 DTCs! File ECU3.odx-d contains 0 DTCs! File ECU4.odx-d contains 0 DTCs! File ECU5.odx-d contains 0 DTCs! File ECU6.odx-d contains 20 DTCs! File ECU7.odx-d contains 36 DTCs! File ECU8.odx-d contains 28 DTCs! File ECU9.odx-d contains 6 DTCs! File ECU10.odx-d contains 99 DTCs! File ECU11.odx-d contains 18 DTCs! File ECU12.odx-d contains 101 DTCs! File ECU13.odx-d contains 64 DTCs! File ECU14.odx-d contains 133 DTCs! File ECU15.odx-d contains 10 DTCs! File ECU16.odx-d contains 1 DTCs! File ECU17.odx-d contains 43 DTCs! File ECU18.odx-d contains 65 DTCs! File ECU19.odx-d contains 30 DTCs! All Files together contain 802 DTCs.
Die Schnittstelle
Attr
erweitert Node. Sie steht für ein Attribut eines
Elements. Objekte vom Typ
Attr
erben von
Node
. Dabei wird
Node
um drei Attribute zur Abbildung der Charakteristika
eines XML-Attributs erweitert.
DOM betrachtet Attribute eher als Eigenschaften von
Elementen denn als eigenständige Objekte mit einer
eigenen Identität. Sie werden in DOM demnach nicht als
Kindknoten des Elements betrachtet, das sie beschreiben.
Attribute werden werden von DOM nicht als Teil des
Dokumentbaums gesehen. Die Eigenschaften
parentNode
,
previousSibling
und
nextSibling
sind für
Attr
-Objekte nicht definiert und haben den Nullwert.
In DOM werden alle Attributwerte als einfache Zeichenketten dargestellt, auch wenn eine DTD oder ein Schema sie als einem bestimmten Typ zugehörig (z.B. als Token) definiert.
interface Attr : Node {
readonly attribute DOMString name;
readonly attribute boolean specified;
attribute DOMString value;
// raises(DOMException) on setting
// Introduced in DOM Level 2:
readonly attribute Element ownerElement;
// Introduced in DOM Level 3:
readonly attribute TypeInfo schemaTypeInfo;
readonly attribute boolean isId;
};
Die Attribut-spezifischen Eigenschaften werden durch den
Attributnamen (
name
) und seinen Wert (
value
) abgebildet.
Ferner ist verfügbar, ob es sich um ein im eingelesenen
Quelldokument auftretendes Attribut handelt (
specified
hat den Wert
true
), oder durch den Parser der in der DTD oder dem Schema
festgelegte Vorgabewert geliefert wird.
schemaTypeInfo
liefert Information über den Typ, der mit dem Attribut
verbunden ist. Einen Verweis auf das umgebende Element
liefert das Attribut
ownerElement
.
Im folgenden Codebeispiel sollen verschiedene Informationen, die in Form von Attributen vorliegen, ermittelt werden. Als Eingabe dient eine um die DOCTYPE-Deklaration erweiterte Variante der Projektverwaltung.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ProjektVerwaltung SYSTEM "projektverwaltung.dtd">
<ProjektVerwaltung>
<Person PersID="Pers01" mitarbeitInProjekt="Prj01">
<Vorname>Hans</Vorname>
<Nachname>Hinterhuber</Nachname>
</Person>
<Person PersID="Pers02" mitarbeitInProjekt="Prj02">
<Vorname>Franz</Vorname>
<Vorname>Xaver</Vorname>
<Nachname>Obermüller</Nachname>
<Qualifikationsprofil>
IT-Kompetenz verschiedene Betriebssysteme und <Leistungsstufe>professionelle</Leistungsstufe>
<Qualifikation>Programmierung</Qualifikation> verschiedener Programmiersprachen
<Qualifikation>Entwickler</Qualifikation> von 1988-1990
<Qualifikation>Projektleiterfunktion</Qualifikation> von 1990-93 im X42-Projekt in Abteilung AB&C
</Qualifikationsprofil>
</Person>
<Person PersID="Pers03" mitarbeitInProjekt="Prj02">
<Vorname>Fritz</Vorname>
<Nachname>Meier</Nachname>
</Person>
<Projekt ID="Prj01" Projektleiter="Pers01" Mitarbeiter="Pers01"/>
<Projekt ID="Prj02" Projektleiter="Pers02" Mitarbeiter="Pers03"/>
</ProjektVerwaltung>
Zunächst werden alle Elemente des Typs
Projekt
in einer
NodeList
zusammengestellt.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(args[0]);
Element theRootElement = document.getDocumentElement();
NodeList projects = theRootElement.getElementsByTagName("Projekt");Danach werden alle Elemente der Knotenmenge durchlaufen, und im Falle der Existenz (geprüft mit hasAttributes) verschiedene Charakteristika des Attributs ausgegeben.
for (int i = 0; i < projects.getLength(); i++) {
Element theElement;
if ((theElement = (Element) projects.item(i)).hasAttributes()) {
Attr theAttribute = theElement.getAttributeNode("ID");
System.out.println("Attribute: " + theAttribute.getName());
System.out.println("value=" + theAttribute.getValue());
System.out.println("specified=" + theAttribute.getSpecified());
theAttribute = theElement.getAttributeNode("budget");
System.out.println("Attribute: " + theAttribute.getName());
System.out.println("value=" + theAttribute.getValue());
System.out.println("specified=" + theAttribute.getSpecified());
}//if
}//forEin Aufruf ergibt folgendes Ergebnis:
Attribute: ID value=Prj01 specified=true Attribute: budget value=10000 specified=false Attribute: ID value=Prj02 specified=true Attribute: budget value=10000 specified=false
Die Auswertungen zum ID-Attribut sind direkt aus dem XML-Eingabedokument ersichtlich.
Woher jedoch kommen die Werte für das Attribut
budget
(Auflösung mit Taste
n
)?
Der XML-Prozessor erhält seine Informationen über
budget
aus der referenzierten Dokument Typ Deklaration. In
ihr ist das Attribut mit dem Vorgabwert 10.000
definiert. Dieser Wert wird an die Applikation
zurückgegeben, wenn keine andere Belegung im
Dokument gefunden wird. Dies ist für beide
Projekt
-Elemente der Fall. Verfügt das Eingabedokument über
keine DOCTYPE-Deklaration, so kann diese Information
nicht ausgewertet werden.
Die Schnittstelle ProcessingInstruction steht für eine
processing instruction
, wie sie in XML verwendet wird, um dem verarbeitenden
Prozessor Hinweise zur Verarbeitung des XML-Dokuments zu
übergeben.
Der Inhalt einer
processing instruction
wird keiner Prüfung unterzogen.
Die Processing Instruction enthält folgende zwei
Eigenschaften:
interface ProcessingInstruction : Node {
readonly attribute DOMString target;
attribute DOMString data;
// raises(DOMException) on setting
};
target
: Der Name des Prozessors / der Applikation, die die
Processing Instruction berücksichtigen soll.
data
: der Inhalt der Processing Instruction.
Die Schnittstelle
CharacterData
erweitert
Node
um eine Reihe von Attributen und Methoden, mit denen auf
Zeichendaten in DOM zugegriffen werden kann. Es gibt
kein DOM Objekt, das direkt dieser Schnittstelle
entspricht. Es handelt sich hierbei vielmehr um eine
Sammlung von Methoden und Attribute, die ansonsten für
jedes Objekt, das diese Schnittstelle erweitert (z.B.
Text
, neu definiert werden hätten müssen.
interface CharacterData : Node {
attribute DOMString data;
// raises(DOMException) on setting
// raises(DOMException) on retrieval
readonly attribute unsigned long length;
DOMString substringData(in unsigned long offset,
in unsigned long count)
raises(DOMException);
void appendData(in DOMString arg)
raises(DOMException);
void insertData(in unsigned long offset,
in DOMString arg)
raises(DOMException);
void deleteData(in unsigned long offset,
in unsigned long count)
raises(DOMException);
void replaceData(in unsigned long offset,
in unsigned long count,
in DOMString arg)
raises(DOMException);
};
data
: Die Zeichendaten des Knotens als
DOMString
Datentyp. The DOM implementation may not put arbitrary
limits on the amount of data that may be stored in a
CharacterData node. However, implementation limits may
mean that the entirety of a node's data may not fit into
a single DOMString. In such cases, the user may call
substringData to retrieve the data in appropriately
sized pieces.
length
: Gibt die Anzahl der 16-bit Einheiten an, die über die
Methoden
data
und
substringData
verfügbar sind. Leere Zeichenketten liefern den Wert
0
.
appendData
: dient dazu, den übergebenen String and Ende der Daten
des Knotens anzuhängen. Bei Erfolg, kann mit
data
auf die so zusammengefügte Zeichenkette zugegriffen
werden.
deleteData
: Entfernt einen Bereich von 16-bit Einheiten vom
Knoten.
insertData
: Fügt einen String am angegebenen Ort ein.
replaceData
: Ersetzt die Zeichen am angegebenen Ort durch die
übergebene Zeichenkette.
substringData
: Liefert einen Teilstring aus dem angegebenen Bereich
zurück.
Die Schnittstelle Text erweitert
CharacterData
. Sie steht für textuellen Inhalt von ELementen oder
Attributen.
Wenn innerhalb eines Elements kein Markup vorkommt, ist
der enthaltene Text in einem einzigen Objekt vom Typ
Text
enthalten. Dieses Objekt ist das einzige Kind des
Elements.
Andernfalls wird das enthaltene Markup analysiert und entsprechende Knoten (Elemente, Attribute, Kommentare, Text) als Kindknoten des Elements erzeugt.
Zusätzlich zu den in
CharacterData
bereits definierten Attributen und Methoden definiert
Text
folgende:
interface Text : CharacterData {
// Introduced in DOM Level 3:
readonly attribute boolean isElementContentWhitespace;
// Introduced in DOM Level 3:
readonly attribute DOMString wholeText;
Text splitText(in unsigned long offset)
raises(DOMException);
// Introduced in DOM Level 3:
Text replaceWholeText(in DOMString content)
raises(DOMException);
};
isElementContentWhitespace
: Gibt zurück, ob dieser Textkniten Leerzeichen enthält,
der
ignoriert
werden kann.
wholeText
:Gibt den Text all der Textknoten zurück, die vom
aktuellen Knoten aus besucht werden können, ohne die
Grenzen von Elementmarkup, Kommentaren oder Processing
Instructions zu überschreiten.
String myStr = contentNode.getWholeText();
System.out.println("Content of TextNode is: " + myStr);
replaceWholeText
: Ersetzt den Text des aktuellen Knotens, der vom
aktuellen Knoten aus besucht werden kann, ohne die
Grenzen von Elementmarkup, Kommentaren oder Processing
Instructions zu überschreiten.
contentNode = contentNode.replaceWholeText("yo");
splitText
: Spaltet den Knoten an der angegebenen Position in zwei
Geschwisterknoten auf.
Das hier vorgestellte Beispiel versammelt Zugriff auf alle vorgestellten Methoden zur Textknotenverarbeitung.
Es extrahiert zunächst alle Paragraphen
p
(in denen üblicherweise Textinhalt steht) aus dem
Eingabedokument. Die weitere Textverarbeitung findet
dann aus Gründen der Einfachheit auf dem Inhalt des
ersten extrahierten Paragraphen statt.
Es werden zuerst einige Statistiken zum textuellen
Inhalt auf
stdout
ausgegegeben, bevor der Text zum besseren Verständnis
dieser ermittelten Statistiken zeichenweise ausgegeben
wird.
Im Anschluß wird der Textinhalt des einen Knotens auf zwei Textknoten aufgeteilt, um danach durch neuen Text ersetzt zu werden.
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class DOMText {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(args[0]);
Element theRootElement = document.getDocumentElement();
NodeList paragraphs = theRootElement.getElementsByTagName("p");
Element theElement = (Element) paragraphs.item(0);
NodeList elemContent = theElement.getChildNodes();
System.out.println("Nodelist of Element Content has " + elemContent.getLength() + " items");
Text contentNode = (Text) elemContent.item(0);
System.out.println("Name of Node is: " + contentNode.getNodeName());
System.out.println("Node is of Type " + contentNode.getNodeType());
System.out.println("Length of Text is: " + contentNode.getLength());
String myStr = contentNode.getWholeText();
System.out.println("Content of TextNode is: " + myStr);
for (int i=0; i< contentNode.getLength(); i++) {
System.out.println("Text at position " + i + " : " + contentNode.substringData(i,1) );
}
Text newcontentNode = contentNode.splitText(contentNode.getLength()/2);
String newStr = newcontentNode.getData();
String oldStr = contentNode.getData();
System.out.println("Content of Text Node #1 is: " + oldStr);
System.out.println("Content of Text Node #2 is: " + newStr);
System.out.println("getWholeText() gets data from ALL nodes: " + newcontentNode.getWholeText());
contentNode = contentNode.replaceWholeText("yo");
System.out.println ("Content of Node after text replacement is: " + contentNode.getWholeText());
} //main()
} //class DOMTextAngewendet auf folgendes Eingabedokument...
<test> <p> bar & foo </p> </test>
... ergibt sich folgende Ausgabe:
Nodelist of Element Content has 1 items Name of Node is: #text Node is of Type 3 Length of Text is: 18 Content of TextNode is: bar & foo Text at position 0 : Text at position 1 : Text at position 2 : Text at position 3 : b Text at position 4 : a Text at position 5 : r Text at position 6 : Text at position 7 : Text at position 8 : Text at position 9 : & Text at position 10 : Text at position 11 : Text at position 12 : Text at position 13 : f Text at position 14 : o Text at position 15 : o Text at position 16 : Text at position 17 : Content of Text Node #1 is: bar Content of Text Node #2 is: & foo getWholeText() gets data from ALL nodes: bar & foo Content of Node after text replacement is: yo
Das abschließende Beispiel zeigt die Nutzung aller vorgestellten Schnittstellen zur Konstruktion eines neuen XML-Dokuments.
Folgendes Dokument soll komplett im Hauptspeicher erzeugt werden und danach über die Standardausgabe ausgegeben werden.
<?xml version="1.0"?>
<?myPI this is a test?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
<head>
<title>Testpage</title>
</head>
<body>
<p>This is a <a href="http://www.barbara-zengler.de">link</a>
<svg:svg width="4cm" height="8cm">
<svg:ellipse cx="2cm" cy="4cm" rx="2cm" ry="1cm"/>
</svg:svg>
</p>
</body>
</html>Zuerst wird ein Dokument erzeugt und die Processing Instruction als Kindelement an das Dokument hinzugefügt.
public class DOMFinalExample {
public static void main(String[] args) throws Exception {
// implementation specific part begins ...
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document myDocument = builder.newDocument();
// ... ends
myDocument.appendChild(myDocument.createProcessingInstruction("myPI", "this is a test"));
Danach wird das
html
-Element als Kindelement des Dokuments im korrekten
Namensraum erzeugt sowie die beiden Attribute
xmlns
und
xmlns:svg
hinzugeügt.
Element htmlElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "html");
//htmlElement.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
htmlElement.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg");
myDocument.appendChild(htmlElement);
In einem nächsten Schritt werden
head
- und
title
-Element samt textuellem Inhalt erzeugt und an den
jeweils korrekten Stellen in den Baum eingefügt.
Element headElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "head");
htmlElement.appendChild(headElement);
Element titleElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "title");
titleElement.appendChild(myDocument.createTextNode("Testpage"));
headElement.appendChild(titleElement);
Analog zum
head
-Element wird das
body
-Element erzeugt und als Kindelement an das
html
-Element angehängt.
Element bodyElement = myDOcument.createElementNS("http://www.w3.org/1999/xhtml", "body");
htmlElement.appendChild(bodyElement);
Element
p
sowie dessen Kindelement
a
werden samt textuellem Inhalt erstellt und in die
Dokumentstruktur eingebunden.
Element pElement = (Element) bodyElement.appendChild((myDocument.createElementNS("http://www.w3.org/1999/xhtml", "p")));
Element aElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "a");
aElement.setAttribute("href", "http://www.barbara-zengler.de");
aElement.appendChild(myDocument.createTextNode("link"));
pElement.appendChild(myDocument.createTextNode("This is a"));
pElement.appendChild(aElement);
Schließlich wird das Element
svg
im Namensraum
http://www.w3.org/2000/svg
mit seinen Attributen
width
und
height
sowie dessen Kindelement
ellipse
mit Attributen erzeugt und in den Dokumentbaum
eingehängt.
Element svgElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:svg");
pElement.appendChild(svgElement);
svgElement.setAttribute("width", "4cm");
svgElement.setAttribute("height", "8cm");
Element ellipseElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:ellipse");
ellipseElement.setAttribute("cx", "2cm");
ellipseElement.setAttribute("cy", "4cm");
ellipseElement.setAttribute("rx", "2cm");
ellipseElement.setAttribute("ry", "1cm");
svgElement.appendChild(ellipseElement);
In früheren DOM Spezifikationen wurden durch den
Standard weder lesende Operationen definiert, noch die
Möglichkeiten zum Schreiben der erstellen
Objektstrukturen. Die hierfür notwendigen Operationen
wurden in konkreten Implementierungen durch proprietären
Code umgesetzt.
Im vorliegenden Beispiel wurde mit einer früheren
Implementierung von SUNs JDK die dort vorgeschlagene
(umständliche) Verfahrensweise genutzt: zur Ausgabe ein
StreamResult-Objekt als Ergebnis der
Dokumenttransformation mittels XSLT zu erzeugen. Dies
funktioniert mit aktuellen JDK-Versionen nicht mehr.
Ein- und Ausgabe sind seit DOM Level 3 wesentlich einfacher gestaltet: DOM Load and Save .
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class DOMFinalExample {
public static void main(String[] args) throws Exception {
// implementation specific part begins ...
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document myDocument = builder.newDocument();
// ... ends
myDocument.appendChild(myDocument.createProcessingInstruction("myPI", "this is a test"));
Element htmlElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "html");
//htmlElement.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
htmlElement.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg");
myDocument.appendChild(htmlElement);
Element headElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "head");
htmlElement.appendChild(headElement);
Element titleElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "title");
titleElement.appendChild(myDocument.createTextNode("Testpage"));
headElement.appendChild(titleElement);
Element bodyElement = myDOcument.createElementNS("http://www.w3.org/1999/xhtml", "body");
htmlElement.appendChild(bodyElement);
// this is the usual sequence ...
Element pElement = (Element) bodyElement.appendChild((myDocument.createElementNS("http://www.w3.org/1999/xhtml", "p")));
Element aElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "a");
aElement.setAttribute("href", "http://www.barbara-zengler.de");
aElement.appendChild(myDocument.createTextNode("link"));
pElement.appendChild(myDocument.createTextNode("This is a"));
pElement.appendChild(aElement);
Element svgElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:svg");
pElement.appendChild(svgElement);
svgElement.setAttribute("width", "4cm");
svgElement.setAttribute("height", "8cm");
Element ellipseElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:ellipse");
ellipseElement.setAttribute("cx", "2cm");
ellipseElement.setAttribute("cy", "4cm");
ellipseElement.setAttribute("rx", "2cm");
ellipseElement.setAttribute("ry", "1cm");
svgElement.appendChild(ellipseElement);
//Output - does not work anymore!
//TransformerFactory transFactory = TransformerFactory.newInstance();
//Transformer myTransformer = transFactory.newTransformer();
//DOMSource src = new DOMSource(myDocument);
//System.out.println(myDocument);
//myTransformer.transform(src, new StreamResult());
} //main()
} //class DOMFinalExampleDie Spezifikation DOM Level 3: Load and Save definiert eine plattform- und programmiersprachenunabhängige Schnittstelle zum Laden und Speichern von XML-Dokumenten. Sie beinhaltet das dynamische Laden eines Dokumentinhalts in ein DOM Dokument und umgekehrt die Serialisierung eines DOM Dokumentes in ein XML-Dokument. Softwareentwickler und Autoren von Webskripten können hiermit XML-Inhalt sehr komfortabel laden und speichern. Auch die Filterung des Inhalts während des Ladens und Speicherns ist möglich.
Folgende Schnittstellen werden in DOM Load and Save definiert
DOMImplementationLS
DOMImplementation
Schnittstelle und bringt Fabrikmethoden mit sich, um
die zum Laden und Speichern nötigen Objekte zu
erzeugen.
LSParser
geparstwerden.
LSSerializer
LSParserFilter
LSSerializerFilter
LSInput
LSOutput
LSResourceResolver
Folgende zu DOM Core zusätzlichen Datentypen werden in Load and Save definiert:
LSInputStream
java.io.InputStream
abgebildet.
LSOutputStream
java.io.OutputStream
abgebildet.
LSReader
java.io.Reader
abgebildet.
LSWriter
java.io.Writer
abgebildet.
Die im folgenden besprochenen grundlegenden
Schnittstellen müssen von zu DOM Load and Save konformen
Modulen unterstützt werden.
Sie sind mit der Methode
hasFeature
mit den Parametern
LS
(für
Load and Save
) und
3.0
(für
DOM Level 3.0
)abfragbar.
Core supported XML supported HTML not supported XPath not supported Validation not supported Events not supported LS supported Views not supported Traversal not supported LS-Async not supported StyleSheets not supported Range not supported HTMLEvents not supported MutationEvents not supported UIEvents not supported CSS not supported MutationNameEvents not supported CSS2 not supported KeyboardEvents not supported TextEvents not supported MouseEvents not supported
Während Lese- oder Schreibvorgängen können Fehler
auftreten, die dazu führen, daß die Verarbeitung nicht
fortgesetzt werden kann. In diesem Fall tritt ein Fehler
der Art
LSException
auf. Durch die Abfrage eines Integerwerts kann die Art
des Fehler noch näher bestimmt werden:
81 (PARSE_ERR)
82 (SERIALIZE_ERR)
DOMImplementationLS
DOMImplementationLS
enthält die Fabrikmethoden, um Parser, Serializer, sowie
Input- und Outputobjekte aus
Load and Save
zu erzeugen.
interface DOMImplementationLS {
// DOMImplementationLSMode
const unsigned short MODE_SYNCHRONOUS = 1;
const unsigned short MODE_ASYNCHRONOUS = 2;
LSParser createLSParser(in unsigned short mode,
in DOMString schemaType)
raises(DOMException);
LSSerializer createLSSerializer();
LSInput createLSInput();
LSOutput createLSOutput();
};
Eine Instanz dieser Schnittstelle kann durch Aufruf der
Methode
DOMImplementation.getFeature("LS", "3.0")
erhalten werden (sofern DOM Level 3 Core unterstützt
wird) , oder alternativ durch
Casten
einer
DOMImplementation
-Instanz.
public class DOMImplementationExample {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation implementation = builder.getDOMImplementation();
DOMImplementationLS impLS = (DOMImplementationLS) implementation.getFeature("LS","3.0");LSParser
Die Schnittstelle bietet die Möglichkeit, aus
verschiedenen Eingabequellen einen DOM Baum zu
erstellen.
Asynchrone LSParser bieten die Möglichkeit, Event
Listener für Ereignisse zu registrieren. Sie
implementieren die Schnittstelle
EventTarget
.
Folgende Ereignisse sind unterstützt:
load
progress
LSParser - Attribute
interface LSParser {
readonly attribute DOMConfiguration domConfig;
attribute LSParserFilter filter;
readonly attribute boolean async;
readonly attribute boolean busy;domConfig
filter
async
busy
LSParser - Operationen
Document parse(in LSInput input)
raises(DOMException,
LSException);
Document parseURI(in DOMString uri)
raises(DOMException,
LSException);
void abort();
Node parseWithContext(in LSInput input,
in Node contextArg,
in unsigned short action)
raises(DOMException,
LSException);parse
LSInput
identifizierte Ressource. Gibt das erstellte
Document
zurück.
parseURI
abort
parseWithContext
LSInput
identifiziert wird. Der Inhalt wird in ein
existierendes Dokument eingefügt, und zwar an der
Position, die durch das Attribute
context
festgelegt wird. Die Art der Verarbeitung wird durch
action
(
ACTION_APPEND_AS_CHILDREN,
ACTION_REPLACE_CHILDREN, ACTION_INSERT_BEFORE,
ACTION_INSERT_AFTER, ACTION_REPLACE
) spezifiziert.
Zunächst muß mit Hilfe der Methode
DOMImplementationLS.createLSParser()
eine Instanz eines LSParsers erzeugt werden.
// obtain a parser instance and parse file given as argument on command line
LSParser myParser = impLS.createLSParser((short) 1, null);
Mit der Methode
parseURI
kann ein Dokument eingelesen werden, z.B. auch eine
durch Kommandozeile übergebene Datei.
//LSParser myParser = impLS.createLSParser(MODE_SYNCHRONOUS, null);
Document myFirstDocument = myParser.parseURI(args[0]);LSInput
Die andere Alternative, ein Dokument einzulesen, ist
über die Schnittstelle
LSInput
. Sie repräsentiert eine Eingabequelle für Daten.
Die Schnittstelle kapselt Information über die Informationsquelle, z.B. einen Public Identifier, einen System Identifier, einen Basis-URI, einen ByteStream und/oder einen CharacterStream.
Die Schnittstelle kann erzeugt werden, indem die
Fabrikmethode
createLSInput()
auf die Schnittstelle
DOMImplementationLS
angewendet wird.
Mit
LSInput
ist ein Parser in der Lage, verschiedene Eingabequellen
komfortabel einzulesen. Die Engabequellen können durch
entsprechende
set
- Methoden auf der Schnittstelle angegeben werden. Sie
werden in der angegebenen Reihenfolge ausgewertet:
interface LSInput {
// Depending on the language binding in use,
// this attribute may not be available.
attribute LSReader characterStream;
attribute LSInputStream byteStream;
attribute DOMString stringData;
attribute DOMString systemId;
attribute DOMString publicId;
attribute DOMString baseURI;
attribute DOMString encoding;
attribute boolean certifiedText;
};characterStream
setCharacterStream(Reader characterStream)
)
byteStream
setByteStream(InputStream byteStream)
)
stringData
setStringData(String stringData)
)
systemId
setSystemId(String systemId)
)
publicId
setPublicId(String publicId)
)
Mit der Methode
parse(LSInput input)
wird schlußendlich die Eingabe durch den Parser
verarbeitet.
// obtain LSInput and read in file
LSInput myInput = impLS.createLSInput();
FileInputStream myFIS = new FileInputStream("namespace15-noBOM.xml");
myInput.setByteStream(myFIS);
Document mySecondDocument = myParser.parse(myInput);LSSerializer
Der
LSSerializer
dient der Serialisierung (dem Schreiben) eines DOM
Knotens, typischerweise eines ganzen Dokuments, nach
XML. Die XML Daten werden dabei entweder in einen String
oder in einen OutputStream geschrieben. Während der
Serialisierung werden Namensräume insofern "korrigiert",
daß der leere Namensraum (der prinzipiell in
XML-Dokumenten vorkommen darf) nicht ausgegeben wird
sowie Namensräume nach einem spezifizierten Algorithmus
auf ihre Konsistenz geprüft und bei Bedarf korrigiert
werden (vgl. Appendix B.1, "Namespace normalization",
aus [DOM Level 3 Core]).
Das (konfigurierbare) Standardverhalten eines
LSSerializers beinhaltet, daß für Dokumentknoten der
XML-Prolog sowie das gesamte Dokument ausgegeben wird.
Für Dokumentteilbäume (Knotentyp
DocumentFragment
) werden alle Kindknoten in der Reihenfolge ihres
Auftretens ausgegeben.
Alle anderen Knotentypen werden in ihrer entsprechenden
XML-Repräsentation ausgegeben.
interface LSSerializer {
readonly attribute DOMConfiguration domConfig;
attribute DOMString newLine;
attribute LSSerializerFilter filter;
boolean write(in Node nodeArg,
in LSOutput destination)
raises(LSException);
boolean writeToURI(in Node nodeArg,
in DOMString uri)
raises(LSException);
DOMString writeToString(in Node nodeArg)
raises(DOMException,
LSException);
};Hinweis: Die Serialisierung von Knoten erzeugt nicht immer wohlgeformtes XML!
Im nachfolgenden Beispiel werden zwei Serializer für
zwei Dokumente erzeugt. Dabei wird jeweils der
Dokumentknoten mit Hilfe der Methode
writeToString
serialisiert. Das erste Dokument wird mit
System.out.println
direkt auf die Standardausgabe ausgegeben. Das zweite
Dokument wird zunächst in der Variable
outStr
vom Typ
String
gespeichert.
// create a Serializer and print first document on stdout
LSSerializer myFirstSerializer = impLS.createLSSerializer();
System.out.println(myFirstSerializer.writeToString(myFirstDocument));
// create a Serializer for second document
LSSerializer mySecondSerializer = impLS.createLSSerializer();
String outStr = mySecondSerializer.writeToString(mySecondDocument);LSOutput
LSOutput
repräsentiert (und kapselt) ein Ausgabeziel für Daten,
z.B. eine URI, einen ByteStream, eine Basis-URI und/oder
einen CharacterStream.
Die Schnittstelle kann erzeugt werden, indem die
Fabrikmethode
createLSOutput()
auf die Schnittstelle
DOMImplementationLS
angewendet wird.
Mit
LSOutput
ist ein Parser in der Lage, verschiedene Ausgabequellen
komfortabel zu verwenden. Die Ausgabequellen können
durch entsprechende
set
- Methoden auf der Schnittstelle angegeben werden. Sie
werden in der angegebenen Reihenfolge ausgewertet:
characterStream
setCharacterStream(Writer characterStream)
)
byteStream
setByteStream(OutputStream byteStream)
)
systemId
setSystemId(String systemId)
)
Im nachfolgenden Codeauszug werden Daten in eine Datei
ausgegeben. Dazu wird ein
FileOutputStream
erzeugt und dieser durch
setByteStream
mit LSOutput verbunden.
// Obtain LSOutput
LSOutput myOutput = impLS.createLSOutput();
FileOutputStream myFOS = new FileOutputStream("DOMImplementationExampleOutput.xml");
myOutput.setByteStream(myFOS);
myFOS.write(outStr.getBytes());Im nachfolgenden Beispiel ist die Verwendung aller Schnittstellen aus DOM Load and Save demonstriert.
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSParser;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class DOMImplementationExample {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation implementation = builder.getDOMImplementation();
DOMImplementationLS impLS = (DOMImplementationLS) implementation.getFeature("LS","3.0");
// obtain a parser instance and parse file given as argument on command line
LSParser myParser = impLS.createLSParser((short) 1, null);
//LSParser myParser = impLS.createLSParser(MODE_SYNCHRONOUS, null);
Document myFirstDocument = myParser.parseURI(args[0]);
// obtain LSInput and read in file
LSInput myInput = impLS.createLSInput();
FileInputStream myFIS = new FileInputStream("namespace15-noBOM.xml");
myInput.setByteStream(myFIS);
Document mySecondDocument = myParser.parse(myInput);
// create a Serializer and print first document on stdout
LSSerializer myFirstSerializer = impLS.createLSSerializer();
System.out.println(myFirstSerializer.writeToString(myFirstDocument));
// create a Serializer for second document
LSSerializer mySecondSerializer = impLS.createLSSerializer();
String outStr = mySecondSerializer.writeToString(mySecondDocument);
// Obtain LSOutput
LSOutput myOutput = impLS.createLSOutput();
FileOutputStream myFOS = new FileOutputStream("DOMImplementationExampleOutput.xml");
myOutput.setByteStream(myFOS);
myFOS.write(outStr.getBytes());
}
} // end DOMImplementationExampleEin Aufruf des Beispiels ...
java DOMImplementationExample erstes-XML-dokument.xml
... ergibt folgendes Ausgabe auf
stdout
:
㰿硭氠癥牳楯渽∱⸰∠敮捯摩湧㴢啔䘭ㄶ∿㸊㱖潲汥獵湧㸊†㱐晬楣桴晡捨⼾ਠ‼䡯捨獣桵汥㹆慣桨潣桳捨畬攠䅵杳扵牧㰯䡯捨獣桵汥㸊†㱓瑵摩敮条湧敭敳瑥爽∳∾䥁䴼⽓瑵摩敮条湧㸊†㱔楴敬㹘䵌㰯呩瑥氾ਠ‼卥浥獴敲㹗匠㈰〸⼲〰㤼⽓敭敳瑥爾ਠ⁍潮瑡本‰㠺〰栠ⴠ〹㨳とਠ‼偲慫瑩歵派卥浩湡爼⽐牡歴楫畭㸊㰯噯牬敳畮朾
Zusätzlich wird die Datei
DOMImplementationExampleOutput.xml
erzeugt und mit dem Inhalt der zweiten eingelesenen
Datei befüllt.
Das nach DOM LS einführende Beispiel (im Hauptspeicher erzeugtes Dokument) soll hier nochmals aufgeführt und mit DOM LS ausgegeben werden.
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.OutputStream;
import java.io.FileOutputStream;
import org.w3c.dom.ls.LSSerializer;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
public class DOMFinalExample_LS {
public static void main(String[] args) throws Exception {
// implementation specific part begins ...
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document myDocument = builder.newDocument();
DOMImplementation implementation = builder.getDOMImplementation();
DOMImplementationLS impLS = (DOMImplementationLS) implementation.getFeature("LS","3.0");
// ... ends
myDocument.appendChild(myDocument.createProcessingInstruction("myPI", "this is a test"));
Element htmlElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "html");
//htmlElement.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
htmlElement.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg");
myDocument.appendChild(htmlElement);
Element headElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "head");
htmlElement.appendChild(headElement);
Element titleElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "title");
titleElement.appendChild(myDocument.createTextNode("Testpage"));
headElement.appendChild(titleElement);
Element bodyElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "body");
htmlElement.appendChild(bodyElement);
// this is the usual sequence ...
Element pElement = (Element) bodyElement.appendChild((myDocument.createElementNS("http://www.w3.org/1999/xhtml", "p")));
Element aElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "a");
aElement.setAttribute("href", "http://www.barbara-zengler.de");
aElement.appendChild(myDocument.createTextNode("link"));
pElement.appendChild(myDocument.createTextNode("This is a"));
pElement.appendChild(aElement);
Element svgElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:svg");
pElement.appendChild(svgElement);
svgElement.setAttribute("width", "4cm");
svgElement.setAttribute("height", "8cm");
Element ellipseElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:ellipse");
ellipseElement.setAttribute("cx", "2cm");
ellipseElement.setAttribute("cy", "4cm");
ellipseElement.setAttribute("rx", "2cm");
ellipseElement.setAttribute("ry", "1cm");
svgElement.appendChild(ellipseElement);
// Output via DOM Load and Save
// Serialize Document into String
LSSerializer mySerializer = impLS.createLSSerializer();
String outStr = mySerializer.writeToString(myDocument);
// Output on stdout
System.out.println(outStr);
// In addition, output into file
LSOutput myOutput = impLS.createLSOutput();
FileOutputStream myFOS = new FileOutputStream("DOMFinalExample_LS_Output.xml");
myOutput.setEncoding("UTF-8");
myOutput.setByteStream(myFOS);
mySerializer.write(myDocument, myOutput);
} //main()
} //class DOMFinalExample_LS
Die Ausgabe erfolgt zunächst nach
stdout
sowie in eine Datei.
<?xml version="1.0" encoding="UTF-8"?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg"><head><title>Testpage</title></head><body><p>This is a<a href="http://www.barbara-zengler.de">link</a><svg:svg xmlns:svg="http://www.w3.org/2000/svg" height="8cm" width="4cm"><svg:ellipse cx="2cm" cy="4cm" rx="2cm" ry="1cm"/></svg:svg></p></body></html><?myPI this is a test?>