# writeXML Helper



## Shoox (17. Sep 2010)

Hallo an alle,

ich habe die Aufgabenstellung bekommen einen XML Helper zu schreiben der schreibt 
Also, das was ich bis jetzt habe ist mal das basic zeug:


```
public class WriteXML {
   private Document doc;
   private Element rootElement;
   
   public WriteXML(String root) {
      createDocument();
      rootElement = doc.createElement(root);
      doc.appendChild(rootElement);
   }
   private void createDocument() {
      
      DocumentBuilder docBuilder = null;
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
      try {
         docBuilder = docFactory.newDocumentBuilder();
      } catch (ParserConfigurationException e) {
         System.out.println("Wrong parser configuation:"+e.getMessage());
      }
      doc = docBuilder.newDocument();
   }
```

Ich will jetzt Methoden erstellen wo ich sage: Füge ein neues Element ein.
So weit so einfach nur hängt mein logisches Denkvermögen danach.

Sagen wir ich adde ein Element zum root, an dieses Element häng ich noch eins ran und noch eins und noch eins. Erster Punkt, wie kann ich das so machen das ich sage: das letzte Element was du hinzugefügt hast, an das hängst du das Neue.
Ok, danach sage ich: Füge in das letzte Element 3 Child mit diesen und jenen Values ein.
Dann nimm das vorletzte Element und füge hier Childs dazu.

Im Grunde will ich "einfach" ein xml von oben nach unten schreiben.
Die tagNames sind alle bekannt.

Hoffe es kann mir jemand weiter helfen =)
Dank im vorraus!


----------



## Noctarius (17. Sep 2010)

Am einfachsten speicherst du das als letztes angefügte Element und nutzt dieses zum Anfügen anstatt dem Root-Element. Nach dem Anfügen speicherst du diese Element-Instanz wieder usw


----------



## Shoox (17. Sep 2010)

Hmm... am späten Freitagnachmittag sollte man sich wirklich keinen neuen Aufgaben mehr stellen ^^
danke für diese simple Lösung.


----------



## Noctarius (17. Sep 2010)

Kein Problem ^^ Ich dachte schon ich hätte das etwas verquer erklärt, so dass man es nicht verstehen könnte


----------



## Shoox (30. Sep 2010)

Ein kleineres Problem ist doch noch aufgetreten und zwar schreibt er alles schön brav in ein File, aber wie er schreibt gefällt mir nicht. Hier mal mein fertiger WriteXML Helper:


```
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
 * Diese Klasse erzeugt ein .xml File.<br>
 * Mithilfe der Methoden addElement(), addElementToRoot() und 
 * addElementToSavedElement() kann eine Hierarchie erzeugt werden. <br>
 *
 */
public class WriteXML {
   private Document doc;
   private Element lastElement;
   private Element root;
   private Element savedElement;
   
   /**
    * Erzeugt ein Document und hängt das root-Element an.
    * @param rootName
    */
   public WriteXML(String rootName) {
      createDocument(); 
      root = doc.createElement(rootName);
      doc.appendChild(root);
      lastElement = root;
   }
   
   /**
    * Speichert das letzte Element um einen späteren Zugriff zu ermöglichen.
    */
   public void saveLastElement() {
      savedElement = lastElement;
   }
   
   /**
    * Erzeugt ein Element und hängt es an das gespeicherte Element an.<br>
    * <b>ACHTUNG:</b> Aufruf der Methode saveLastElement() erforderlich.
    * @param tagName
    */
   public void addElementToSavedElement(String tagName) {
      if (savedElement == null) {
         savedElement = root;
      }
      Element newElement = doc.createElement(tagName);
      savedElement.appendChild(newElement);
      lastElement = newElement;
   }
   
   /**
    * Erzeugt ein Element und hängt es an das letzte Erzeugte an.
    * @param tagName
    */
   public void addElement(String tagName) {
      Element newElement = doc.createElement(tagName);
      lastElement.appendChild(newElement);
      lastElement = newElement;
   }
   
   /**
    * Erzeugt ein Element und hängt es an das root-Element an.
    * @param tagName
    */
   public void addElementToRoot(String tagName) {
      Element newElement = doc.createElement(tagName);
      root.appendChild(newElement);
      lastElement = newElement;
   }
   
   /**
    * Erzeugt ein Element und hängt es an das letzte Erzeugte an.
    * @param tagName
    * @param attrName
    * @param attrValue
    */
   public void addElementWithAttribute(String tagName, String attrName, String attrValue) {
      Element newElement = doc.createElement(tagName);
      newElement.setAttribute(attrName, attrValue);
      lastElement.appendChild(newElement);
      lastElement = newElement;
   }
   
   /**
    * Erzeugt ein Child und hängt es and das letzte Erzeugte an. <br>
    * Der Pointer auf das letzte Element wird hierbei nicht verändert.
    * @param tagName
    * @param value
    */
   public void addChild(String tagName, String value) {
      Element child = doc.createElement(tagName);
      child.appendChild(doc.createTextNode(value));
      lastElement.appendChild(child);
   }
   
   /**
    * Erzeugt ein Child und hängt es and das letzte Erzeugte an. <br>
    * Der Pointer auf das letzte Element wird hierbei nicht verändert.
    * @param tagName
    * @param value
    * @param attrName
    * @param attrValue
    */
   public void addChildWithAttribute(String tagName, String value, String attrName, String attrValue) {
      Element child = doc.createElement(tagName);
      child.appendChild(doc.createTextNode(value));
      child.setAttribute(attrName, attrValue);
      lastElement.appendChild(child);
   }
   
   private void createDocument() {
      
      DocumentBuilder docBuilder = null;
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
      try {
         docBuilder = docFactory.newDocumentBuilder();
      } catch (ParserConfigurationException e) {
         System.out.println("Wrong parser configuation:"+e.getMessage());
      }
      doc = docBuilder.newDocument();
   }
   
   /**
    * Erzeugt das .xml File im übergebenen File.
    * @param f
    * @throws Exception
    */
   public void createFile(File f) 
   throws Exception {
      createFile(f.getAbsolutePath());
   }
   
   /**
    * Erzeugt das .xml File an der übergebenen Stelle.
    * @param absolutePath
    * @throws Exception
    */
   public void createFile(String absolutePath) 
   throws Exception {
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();
      DOMSource dom = new DOMSource(doc);
      StreamResult result = new StreamResult(new File(absolutePath));
      transformer.transform(dom, result);
   }
   
   /**
    * Erzeugt das .xml File an der übergebenen Stelle.
    * @param verzeichnis
    * @param fileName
    * @throws Exception
    */
   public void createFile(String verzeichnis, String fileName) 
   throws Exception {
      createFile(verzeichnis+fileName);
   }
}
```

Soweit so gut, nur beim Erzeugen macht er keine Zeilenumbrüche, dh mein fertiges XML-File sieht so aus:

[XML]<?xml version="1.0" encoding="UTF-8" standalone="no"?><blabla><head><date>20100930</date><time>135550<time></head></blabla><product>...[/XML]

Was ist daran schuld, bzw was muss ich anders machen, dass er das File schön leserlich mit richtigen Zeilenumbrüchen und richtigen Tabs erzeugt?
Dank im vorraus

LG, Shoox


----------



## SlaterB (30. Sep 2010)

Java: How to Indent XML Generated by Transformer - Stack Overflow


----------



## Shoox (30. Sep 2010)

```
public void createFile(String absolutePath) 
   throws Exception {
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      transformerFactory.setAttribute("indent-number", new Integer(2));
      Transformer transformer = transformerFactory.newTransformer();
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
      transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
      DOMSource dom = new DOMSource(doc);
      StreamResult result = new StreamResult(new File(absolutePath));
      transformer.transform(dom, result);
   }
```
so funktionierts, danke SlaterB für die schnelle antwort =)

Off-Topic: Bin ehrlich gesagt noch nie in einem Forum gewesen, das so schnell und so freundlich ist wie dieses. Ihr habt mit Sicherheit einen neuen Stammbenutzer gefunden der hoffentlich auch bald anderen weiterhelfen kann (wird zwar noch länger dauern aber irgendwann...).


----------



## Noctarius (30. Sep 2010)

Schau ma, da hast du eine ganz andere Meinung als viele Andere die hier her kommen, eine fertige Lösung präsentiert haben möchten und sich wundern wenn die Leute sich hier weigern ;-)

Aber willkommen am Stammtisch *g*


----------

