700 lines
20 KiB
Java
700 lines
20 KiB
Java
package io.gitlab.jfronny.ImgJava.util;
|
|
|
|
import org.jdom.Attribute;
|
|
import org.jdom.Document;
|
|
import org.jdom.Element;
|
|
import org.jdom.JDOMException;
|
|
import org.jdom.input.SAXBuilder;
|
|
import org.jdom.output.Format;
|
|
import org.jdom.output.XMLOutputter;
|
|
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
|
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
|
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
|
* stehenden Befehle sind wie in Processing realisiert.
|
|
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
|
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
|
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
|
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
|
* <p>
|
|
* Benötigt: jdom-1.1.3.jar
|
|
*
|
|
* @author Thomas Schaller
|
|
* @version 1.0 vom 31.01.2019
|
|
*/
|
|
public class XML {
|
|
// Anfang Attribute
|
|
// XML-Dokumentstruktur
|
|
private Document doc;
|
|
// Zeiger auf das aktuelle Element
|
|
private Element current;
|
|
// Ende Attribute
|
|
|
|
/**
|
|
* Erzeugt ein leeres XMLDokument
|
|
*/
|
|
public XML() {
|
|
this.doc = new Document();
|
|
this.current = null;
|
|
}
|
|
|
|
/**
|
|
* Erzeugt ein XML-Dokument aus einer Datei
|
|
*
|
|
* @param file Dateiname der XML-Datei
|
|
*/
|
|
public XML(Path file) throws IOException, JDOMException {
|
|
loadXML(file);
|
|
}
|
|
|
|
/**
|
|
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
|
*
|
|
* @param doc die XML-Dokumentstruktur
|
|
* @param current Zeiger auf das aktuelle Element
|
|
*/
|
|
private XML(Document doc, Element current) {
|
|
this.doc = doc;
|
|
this.current = current;
|
|
}
|
|
|
|
// Anfang Methoden
|
|
|
|
/**
|
|
* Öffnet das durch den Dateinamen gegebene Dokument
|
|
*
|
|
* @param file Dateiname des XML-Files
|
|
*/
|
|
public void loadXML(Path file) throws IOException, JDOMException {
|
|
doc = null;
|
|
// Das Dokument erstellen
|
|
SAXBuilder builder = new SAXBuilder();
|
|
doc = builder.build(Files.newInputStream(file));
|
|
// Zeiger im Baum auf Root-Element
|
|
current = doc.getRootElement();
|
|
}
|
|
|
|
/**
|
|
* Speichert den XML-Baum im angegebenen Dateinamen
|
|
*
|
|
* @param file Dateiname des XML-Files
|
|
*/
|
|
public void saveXML(Path file) throws IOException {
|
|
// new XMLOutputter().output(doc, System.out);
|
|
XMLOutputter xmlOutput = new XMLOutputter();
|
|
|
|
// display nice nice
|
|
xmlOutput.setFormat(Format.getPrettyFormat());
|
|
OutputStream outputFile = Files.newOutputStream(file);
|
|
System.out.println("Speicher in : " + file.toAbsolutePath());
|
|
xmlOutput.output(doc, outputFile);
|
|
outputFile.close();
|
|
System.out.println("File Saved!");
|
|
}
|
|
|
|
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
|
|
|
/**
|
|
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
|
*
|
|
* @return Vater des aktuellen Objekts.
|
|
*/
|
|
public XML getParent() {
|
|
if (current != null) {
|
|
Element parent = current.getParentElement();
|
|
if (parent == null) {
|
|
return null;
|
|
} else {
|
|
return new XML(doc, parent);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
|
*
|
|
* @return true, wenn Kinder vorhanden sind, sonst false
|
|
*/
|
|
public boolean hasChildren() {
|
|
if (current == null) {
|
|
return doc.hasRootElement();
|
|
} else {
|
|
return current.getChildren().size() > 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
|
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
|
*
|
|
* @return Liste aller Namen der Kinder
|
|
*/
|
|
public String[] listChildren() {
|
|
if (current == null) {
|
|
if (doc.hasRootElement()) {
|
|
String[] names = new String[0];
|
|
names[0] = doc.getRootElement().getName();
|
|
return names;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
List<Element> ch_element = current.getChildren();
|
|
String[] names = new String[ch_element.size()];
|
|
for (int i = 0; i < ch_element.size(); i++) {
|
|
names[i] = ch_element.get(i).getName();
|
|
}
|
|
return names;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
|
*
|
|
* @return Array der Kinder als XML-Objekte
|
|
*/
|
|
public XML[] getChildren() {
|
|
if (current == null) {
|
|
if (doc.hasRootElement()) {
|
|
XML[] ch_xml = new XML[1];
|
|
ch_xml[0] = new XML(doc, doc.getRootElement());
|
|
return ch_xml;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
List<Element> ch_element = current.getChildren();
|
|
XML[] ch_xml = new XML[ch_element.size()];
|
|
for (int i = 0; i < ch_element.size(); i++) {
|
|
ch_xml[i] = new XML(doc, ch_element.get(i));
|
|
}
|
|
return ch_xml;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
|
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
|
*
|
|
* @param name Name der gesuchten Kind-Objekte
|
|
* @return Array der Kinder als XML-Objekte
|
|
*/
|
|
public XML[] getChildren(String name) {
|
|
if (current == null) {
|
|
if (doc.hasRootElement()) {
|
|
XML[] ch_xml = new XML[1];
|
|
ch_xml[0] = new XML(doc, doc.getRootElement());
|
|
if (doc.getRootElement().getName().equals(name)) {
|
|
return ch_xml;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
List<Element> ch_element = current.getChildren(name);
|
|
XML[] ch_xml = new XML[ch_element.size()];
|
|
for (int i = 0; i < ch_element.size(); i++) {
|
|
ch_xml[i] = new XML(doc, ch_element.get(i));
|
|
}
|
|
return ch_xml;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
|
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
|
*
|
|
* @param name Name des gesuchten Kind-Objektes
|
|
* @return Kind als XML-Objekt
|
|
*/
|
|
|
|
public XML getChild(String name) {
|
|
if (current == null) {
|
|
Element e = doc.getRootElement();
|
|
if (e.getName().equals(name)) {
|
|
return new XML(doc, e);
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
String[] names = name.split("/");
|
|
Element e = current;
|
|
int i = 0;
|
|
while (i < names.length) {
|
|
e = e.getChild(names[i]);
|
|
if (e == null) return null;
|
|
i++;
|
|
}
|
|
return new XML(doc, e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Liefert das i. Kind des Elements.
|
|
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
|
*
|
|
* @param i Nummer des Kindes
|
|
* @return Kind als XML-Objekt
|
|
*/
|
|
public XML getChild(int i) {
|
|
if (current == null) {
|
|
return new XML(doc, doc.getRootElement());
|
|
} else {
|
|
List<Element> ch_element = current.getChildren();
|
|
if (i >= ch_element.size()) return null;
|
|
return new XML(doc, ch_element.get(i));
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
|
|
|
/**
|
|
* Frage den Namen des aktuellen Elements ab
|
|
*
|
|
* @return Namen des Elements
|
|
*/
|
|
public String getName() {
|
|
if (current == null) return "";
|
|
return current.getName();
|
|
}
|
|
|
|
/**
|
|
* Setze den Namen des aktuellen Elements.
|
|
*
|
|
* @param name Neuer Name des Elements
|
|
*/
|
|
public void setName(String name) {
|
|
if (current == null) return;
|
|
current.setName(name);
|
|
}
|
|
|
|
/**
|
|
* liefert die Anzahl der Attribute eines Elements.
|
|
*
|
|
* @return Anzahl des Attribute
|
|
*/
|
|
public int getAttributeCount() {
|
|
if (current == null) return 0;
|
|
return current.getAttributes().size();
|
|
}
|
|
|
|
/**
|
|
* liefert zurück, ob das aktuelle Element Attribute hat .
|
|
*
|
|
* @return true, wenn es Attribute gibt
|
|
*/
|
|
public boolean hasAttribute() {
|
|
if (current == null) return false;
|
|
return current.getAttributes().size() > 0;
|
|
}
|
|
|
|
/**
|
|
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
|
*
|
|
* @return Liste der Attributnamen
|
|
*/
|
|
public String[] listAttributes() {
|
|
if (current == null) return null;
|
|
List<Attribute> attr = current.getAttributes();
|
|
String[] names = new String[attr.size()];
|
|
for (int i = 0; i < attr.size(); i++) {
|
|
names[i] = attr.get(i).getName();
|
|
}
|
|
return names;
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @return Wert des Attributs
|
|
*/
|
|
public String getString(String attribute) {
|
|
if (current == null) return "";
|
|
return current.getAttributeValue(attribute);
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
|
* @return Wert des Attributs
|
|
*/
|
|
public String getString(String attribute, String defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
return current.getAttributeValue(attribute, defaultValue);
|
|
}
|
|
|
|
/**
|
|
* Setzt einen Attributwert des aktuellen Elements
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param text neuer Wert des Attributs
|
|
*/
|
|
public void setString(String attribute, String text) {
|
|
if (current == null) return;
|
|
current.setAttribute(attribute, text);
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @return Wert des Attributs als Integer-Zahl
|
|
*/
|
|
public int getInt(String attribute) {
|
|
if (current == null) return 0;
|
|
try {
|
|
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
|
return i;
|
|
} catch (Exception e) {
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
|
* @return Wert des Attributs als Integer-Zahl
|
|
*/
|
|
public int getInt(String attribute, int defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
try {
|
|
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
|
return i;
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Setzt einen Attributwert des aktuellen Elements
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param value neuer Wert des Attributs
|
|
*/
|
|
public void setInt(String attribute, int value) {
|
|
if (current == null) return;
|
|
current.setAttribute(attribute, "" + value);
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @return Wert des Attributs als Float-Zahl
|
|
*/
|
|
public float getFloat(String attribute) {
|
|
if (current == null) return 0;
|
|
try {
|
|
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
|
return i;
|
|
} catch (Exception e) {
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
|
* @return Wert des Attributs als Float-Zahl
|
|
*/
|
|
public float getFloat(String attribute, float defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
try {
|
|
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
|
return i;
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Setzt einen Attributwert des aktuellen Elements
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param value neuer Wert des Attributs
|
|
*/
|
|
public void setFloat(String attribute, float value) {
|
|
if (current == null) return;
|
|
current.setAttribute(attribute, "" + value);
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @return Wert des Attributs als Double-Zahl
|
|
*/
|
|
public double getDouble(String attribute) {
|
|
if (current == null) return 0;
|
|
try {
|
|
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
|
return i;
|
|
} catch (Exception e) {
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Fragt einen Attributwert des aktuellen Elements ab
|
|
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
|
* @return Wert des Attributs als double-Zahl
|
|
*/
|
|
public double getDouble(String attribute, double defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
try {
|
|
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
|
return i;
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Setzt einen Attributwert des aktuellen Elements
|
|
*
|
|
* @param attribute Name des Attributs
|
|
* @param value neuer Wert des Attributs
|
|
*/
|
|
public void setDouble(String attribute, double value) {
|
|
if (current == null) return;
|
|
current.setAttribute(attribute, "" + value);
|
|
}
|
|
|
|
/**
|
|
* Fragt den Inhalt/Text des aktuellen Elements ab
|
|
*
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public String getContent() {
|
|
if (current == null) return "";
|
|
|
|
return current.getText();
|
|
}
|
|
|
|
/**
|
|
* Setzt den Inhalt/Text des aktuellen Elements
|
|
*
|
|
* @param text Neuer Inhalt des Elements
|
|
*/
|
|
public void setContent(String text) {
|
|
if (current == null) return;
|
|
current.setText(text);
|
|
}
|
|
|
|
/**
|
|
* Fragt den Inhalt/Text des aktuellen Elements ab
|
|
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
|
*
|
|
* @param defaultValue Standardtext
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public String getContent(String defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
String t = current.getText();
|
|
if (t.equals("")) t = defaultValue;
|
|
return t;
|
|
}
|
|
|
|
/**
|
|
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
|
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
|
*
|
|
* @param defaultValue Standardwert
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public int getIntContent(int defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
try {
|
|
int i = Integer.parseInt(current.getText());
|
|
return i;
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
|
*
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public int getIntContent() {
|
|
if (current == null) return 0;
|
|
try {
|
|
int i = Integer.parseInt(current.getText());
|
|
return i;
|
|
} catch (Exception e) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setzt den Inhalt des aktuellen Elements
|
|
*
|
|
* @param value Neuer Inhalt des Elements
|
|
*/
|
|
public void setIntContent(int value) {
|
|
if (current == null) return;
|
|
current.setText("" + value);
|
|
}
|
|
|
|
|
|
/**
|
|
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
|
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
|
*
|
|
* @param defaultValue Standardwert
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public float getFloatContent(float defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
try {
|
|
float i = Float.parseFloat(current.getText());
|
|
return i;
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
|
*
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public float getFloatContent() {
|
|
if (current == null) return 0;
|
|
try {
|
|
float i = Float.parseFloat(current.getText());
|
|
return i;
|
|
} catch (Exception e) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setzt den Inhalt des aktuellen Elements
|
|
*
|
|
* @param value Neuer Inhalt des Elements
|
|
*/
|
|
public void setFloatContent(float value) {
|
|
if (current == null) return;
|
|
current.setText("" + value);
|
|
}
|
|
|
|
/**
|
|
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
|
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
|
*
|
|
* @param defaultValue Standardwert
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public double getDoubleContent(double defaultValue) {
|
|
if (current == null) return defaultValue;
|
|
try {
|
|
double i = Double.parseDouble(current.getText());
|
|
return i;
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
|
*
|
|
* @return Inhalt des Elements
|
|
*/
|
|
public double getDoubleContent() {
|
|
if (current == null) return 0;
|
|
try {
|
|
double i = Double.parseDouble(current.getText());
|
|
return i;
|
|
} catch (Exception e) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setzt den Inhalt des aktuellen Elements
|
|
*
|
|
* @param value Neuer Inhalt des Elements
|
|
*/
|
|
public void setDoubleContent(double value) {
|
|
if (current == null) return;
|
|
current.setText("" + value);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
|
|
|
/**
|
|
* Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
|
*
|
|
* @param name Name des neuen Elements
|
|
* @return neues Element als XML-Objekt
|
|
*/
|
|
public XML addChild(String name) {
|
|
Element e = new Element(name);
|
|
if (current == null) { // man ist auf Root-Ebene
|
|
doc.setRootElement(e);
|
|
|
|
} else {
|
|
current.addContent(e);
|
|
} // end of if-else
|
|
return new XML(doc, e);
|
|
}
|
|
|
|
/**
|
|
* liefert das aktuelle Element als jdom-Element-Objekt
|
|
*
|
|
* @return aktuelles Element
|
|
*/
|
|
private Element getCurrent() {
|
|
return current;
|
|
}
|
|
|
|
/**
|
|
* löscht ein Kind des aktuellen Knotens.
|
|
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
|
*
|
|
* @param kid XML-Objekt des Kindes
|
|
*/
|
|
public void removeChild(XML kid) {
|
|
if (current == null) return;
|
|
Element e = kid.getCurrent();
|
|
int index = current.indexOf(e);
|
|
if (index >= 0) {
|
|
current.removeContent(e);
|
|
}
|
|
}
|
|
|
|
}
|