This repository has been archived on 2022-08-05. You can view files and clone it, but cannot push or open issues or pull requests.
school-projects/src/main/java/io/gitlab/jfronny/ImgJava/util/XML.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);
}
}
}