- Initialisierung
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
...
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document docSherd = documentBuilder.newDocument();
Hier wird ein org.w3c.dom.Document erzeugt, indem zuerst eine DocumentBuilderFactory, daraus ein DocumentBuilder
(beides sind abstrakte Klassen, deren Default-Implementierungen in der Java Runtime stecken, aber vor uns weggekapselt sind und durch reine Konfigurationsänderungen
durch andere APIs ersetzt werden könnten)
.
- Wurzelelement anlegen
- Ziel
Das Ergebnis soll so aussehen:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<sherd name="Testdiagramm" version="0.5" width="800" height="600"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd.xsd"
xmlns="http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd">
...
</sherd>
- Wurzelelement und Default-Namespace
Um es zu erzeugen, ist folgender Code nötig:
import org.w3c.dom.Element;
...
Element nodeSherd = docSherd.createElementNS("http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd", "sherd");
docSherd.appendChild(nodeSherd);
Die Document-Instanz nutzen wir, um neue Elemente oder sonstige Knotentypen zu erzeugen. Normalerweise reicht es, die Methode createElement
mit dem Element-Namen als Parameter aufzurufen. Für das Wurzelelement soll allerdings auch ein Default-Namespace eingetragen werden. Der Namespace (beliebige URI)
sieht hier aus wie eine Internet-URL.
Das Ergebnis dieses Aufrufs würde so aussehen:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<sherd xmlns="http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd">
...
</sherd>
"schemaLocation"
Jetzt wird die SchemaLocation für den Default-Namespace "http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd" erzeugt.
Dieses Attribut steckt im Standard-Namespace "http://www.w3.org/2001/XMLSchema-instance", der den Präfix "xsi" haben soll
(d.h. wir müssen diesen Namespace ebenfalls einbinden).
Attribute könnte man über das Document (Methode createAttribute bzw. createAttributeNS) erzeugen. Es gibt allerdings eine
Vereinfachung, um ein Attribut direkt in das Element zu packen.
nodeSherd.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance",
"xsi:schemaLocation",
"http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd http://www.informatik.fh-wiesbaden.de/~knauf/SWTProjekt2009/sherd.xsd");
Hier wird ein Attribut namens "xsi:schemaLocation" definiert, wobei der Namespace-Prefix "xsi" des Attributs mit dem Namespace "http://www.w3.org/2001/XMLSchema-instance" verbunden wird.
Die "schemaLocation" verbindet den "sherd"-Namespace mit der XSD im Web. Für jeden der über "setAttributeNS" definierten Namespaces wird automatisch ein "xmls=..."-Attribut erzeugt.
Quelle: http://bytes.com/groups/xml/468470-how-declare-namespace-prefix-java
- Sonstige Attribute
Jetzt fehlen noch die "sherd"-Attribute "Diagrammname" und "Version":
nodeSherd.setAttribute("name", "Testdiagramm");
nodeSherd.setAttribute("version", "0.5");
nodeSherd.setAttribute("width", "800");
nodeSherd.setAttribute("height", "600");
- Elemente "tabellen", "relations" und "comments" anlegen
Das ist einfach:
Element elementTabellen = docSherd.createElement("tabellen");
nodeSherd.appendChild(elementTabellen);
Element elementRelations = docSherd.createElement("relations");
nodeSherd.appendChild(elementRelations);
Element elementComments= docSherd.createElement("comments");
nodeSherd.appendChild(elementComments);
- Subelement "tabelle" zufügen
Dem "tabellen"-Element wird ein Unterelement "tabelle" mit allen Attributen zugefügt:
Element elementTabelle = docSherd.createElement("tabelle");
elementTabelle.setAttribute("x", ... );
elementTabelle.setAttribute("y", ... );
elementTabelle.setAttribute("width", ... );
elementTabelle.setAttribute("height", ... );
elementTabelle.setAttribute("id", ... );
elementTabelle.setAttribute("tabellenname", ... );
elementTabellen.appendChild(elementTabelle);
Die restlichen Unterelemente werden nach dem gleichen Schema erzeugt.
- Subelement "comment" mit Textinhalt zufügen
Das Element "comment" hat eine Besonderheit: es kann Textinhalt haben. Hier gibt es zwei Möglichkeiten:
Variante 1: Textinhalt
Element elementKommentar = this.docSherd.createElement("comment");
...
elementKommentar.setTextContent("Kommentar 2 mit Markup wie '<', '>', '&'");
elementComments.appendChild(elementKommentar);
Variante 2: "CDATA"-Sektion
Element elementKommentar = this.docSherd.createElement("comment");
...
CDATASection commentText = docSherd.createCDATASection("Kommentar 2 mit Markup wie '<', '>', '&'");
elementKommentar.appendChild(commentText);
elementComments.appendChild(elementKommentar);
Den größten Unterschied zwischen den beiden Varianten erkennt man, wenn man (wie in meinem Beispielprogramm geschehen) "reservierte" Zeichen wie <, > &&
in den Kommentar hängt.
In Variante 1 entsteht dieses XML:
<comment id="501" ...>Kommentar 2 mit Markup wie '<', '>', '&'</comment>
Die reservierten Zeichen werden also automatisch durch Standard-Entities ersetzt.
Variante 2 erzeugt dieses:
<comment id="501" ...><![CDATA[Kommentar 2 mit Markup wie '<', '>', '&']]></comment>
Durch die "<![CDATA[...]]>"-Klammerung müssen reservierte Zeichen nicht mehr maskiert werden. Allerdings darf der Stringinhalt nicht "]]>" enthalten,
denn das würde die Sektion beenden!