package imp; /** * 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. * * Benötigt: jdom-1.1.3.jar * @author Thomas Schaller * @version 1.0 vom 31.01.2019 */ import java.io.File; import java.io.IOException; import java.util.List; import java.util.ArrayList; import java.io.*; import org.jdom.Document; import org.jdom.Element; import org.jdom.Attribute; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; import org.jdom.output.Format; 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 filename Dateiname der XML-Datei */ public XML(String filename) { loadXML(filename); } /** * 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 filename Dateiname des XML-Files */ public void loadXML(String filename) { doc = null; File f = new File(filename); try { // Das Dokument erstellen SAXBuilder builder = new SAXBuilder(); doc = builder.build(f); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // Zeiger im Baum auf Root-Element current = doc.getRootElement(); } /** Speichert den XML-Baum im angegebenen Dateinamen * @param filename Dateiname des XML-Files */ public void saveXML(String filename) { try { // new XMLOutputter().output(doc, System.out); XMLOutputter xmlOutput = new XMLOutputter(); // display nice nice xmlOutput.setFormat(Format.getPrettyFormat()); File f = new File(filename); FileOutputStream outputFile = new FileOutputStream(f); System.out.println("Speicher in : "+f.getAbsolutePath() ); xmlOutput.output(doc, outputFile); outputFile.close(); System.out.println("File Saved!"); } catch (IOException io) { System.out.println(io.getMessage()); } } //----------------------------------------------- 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 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 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 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 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 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(); } /** * 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; } /** * 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 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);} } }