XML-Datei auslesen und ändern

cHucKy51

Mitglied
Hallo, ich möchte eine kleine XML-Datei auslesen und 3 Werte darin verändern können.
Das Auslesen funktioniert tadellos, das Ändern leider nicht. Kann mir einer sagen, woran es liegt?
Die Methode fürs Verändern heißt "writeTableConfig()".

xml-Datei:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<root>
	<tableName>tabelle4.csv</tableName>
	
	<title>Hallo Welt</title>
	
	<color>00FF00</color>
</root>

Hier der Quellcode:
Java:
import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class TableConfig
{
    private String tableName;

    private String windowTitle;

    private String focusColor;

    private NodeList tableNameNodeList;

    private NodeList titleNodeList;

    private NodeList colorNodeList;

    // Liest alle relevanten Daten aus der TableConfig.xml aus
    public void readTableConfig()
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new File("tableConfig.xml"));

            tableNameNodeList = document.getElementsByTagName("tableName");
            tableName = null;

            if (tableNameNodeList.getLength() > 0)
            {
                tableName = tableNameNodeList.item(0).getTextContent().toString();
                setTableName(tableName);
            }

            titleNodeList = document.getElementsByTagName("title");
            windowTitle = null;

            if (titleNodeList.getLength() > 0)
            {
                windowTitle = titleNodeList.item(0).getTextContent().toString();
                setWindowTitle(windowTitle);
            }

            colorNodeList = document.getElementsByTagName("color");
            focusColor = null;

            if (colorNodeList.getLength() > 0)
            {
                focusColor = colorNodeList.item(0).getTextContent().toString();
                setFocusColor(focusColor);
            }
        }

        catch (IOException e)
        {
            System.out.println("IO Fehler");
        }

        catch (ParserConfigurationException e)
        {
            System.out.println("Parser Fehler");
        }

        catch (SAXException e)
        {
            System.out.println("SAX Fehler");
        }
    }

    public void writeTableConfig()
    {
        try
        {
            // Erzeugung eines DocumentBuilderFactory Objekts
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new File("tableConfig.xml"));

            tableNameNodeList = document.getElementsByTagName("tableName");

            if (tableNameNodeList.getLength() > 0)
            {
                tableNameNodeList.item(0).setTextContent(tableName);
            }

            titleNodeList = document.getElementsByTagName("title");

            if (titleNodeList.getLength() > 0)
            {
                titleNodeList.item(0).setTextContent(windowTitle);
            }

            colorNodeList = document.getElementsByTagName("color");

            if (colorNodeList.getLength() > 0)
            {
                colorNodeList.item(0).setTextContent(focusColor);
            }
        }

        catch (IOException e)
        {
            System.out.println("IO Fehler");
        }

        catch (ParserConfigurationException e)
        {
            System.out.println("Parser Fehler");
        }

        catch (SAXException e)
        {
            System.out.println("SAX Fehler");
        }
    }

    public String getFocusColor()
    {
        return focusColor;
    }

    public void setFocusColor(String focusColor)
    {
        this.focusColor = focusColor;
    }

    public String getTableName()
    {
        return tableName;
    }

    public void setTableName(String tableName)
    {
        this.tableName = tableName;
    }

    public String getWindowTitle()
    {
        return windowTitle;
    }

    public void setWindowTitle(String windowTitle)
    {
        this.windowTitle = windowTitle;
    }
}
 
Zuletzt bearbeitet:
Hallo,

gehe ich richtig in der Annahme, dass du es in der Datei ändern willst?
Dann solltest du nämlich die Änderungen in die Datei schreiben. Im Moment änderst du es nur im Speicher und das hat keine Auswirkung auf die Datei.
Um die Datei zu ändern müsstest du dir eine Art XMLOutputter schreiben, da Java von Haus aus sowas nicht anbietet. Dieser könnte so in der Art aussehen

Java:
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;



/**
 * 
 */
public class XMLOutputter
{

  public void output(Document document, OutputStream out ){
    PrintWriter writer = new PrintWriter(out);
    travers(document,writer);
    writer.close();
  }
  
  private void travers(Node node, PrintWriter out){
    switch(node.getNodeType()){
      case Document.DOCUMENT_NODE:
        NodeList list=node.getChildNodes();
        out.println("<?xml version='1.0' encoding='iso-8859-1' ?>");
        for(int i=0; i< list.getLength();i++){
          travers(list.item(i), out);
        }
        break;
      case Document.ELEMENT_NODE: 
        list=node.getChildNodes();
        out.println("<"+node.getNodeName()+">");
        for(int i=0; i< list.getLength();i++){
          travers(list.item(i), out);
        }
        out.println("</"+node.getNodeName()+">");
        break;
      case Document.TEXT_NODE:
        out.println(node.getNodeValue());
        break;
    }
  }

MFG

zEriX
 
Zuletzt bearbeitet:
Hmm, also zunächst mal liest du die XML-Datei doppelt ein, wenn ich das richtig verstehe. Aber nicht weiter schlimm denke ich mal.

In deiner writeTableConfig nimmst du die Änderungen nur am Document vor. Es fehlt der Befehl um das Document wieder als XML-Datei zu speichern. Also irgendwie sowas wie

Code:
XMLOutputter outputter 
  = new XMLOutputter(" ",true);
FileOutputStream output
    = new FileOutputStream("tableConfig.xml");
outputter.output(document,output);

@edit, da ich gerade erst den Beitrag von Zerix gesehen hab, den gab's noch nicht, als ich auf Antworten geklickt hab: Der XMLOutputter, den ich meine, gehört ganz einfach zu jdom. Dom4j hat auch einen, soweit ich weiß. Also kein Grund sich einen komplizierter Weise selbst zu schreiben :)
 
Zuletzt bearbeitet:
Da ich bei der Aufgabe möglichst wenig von nicht-internen Klassen abhängig sein soll, müsste ich wohl das Beispiel von zerix nehmen. Wie binde ich das nun in meinen Code ein? Steh grad irgendwie auf dem Schlauch. Ich muss doch erst wieder tableNameNodeList, titleNodeList und colorNodeList in "document" schreiben oder?
 
Du erstellst eine neue Java-Datei die XMLOutputter heißt und kopierst mein Quelltext dort rein.

In die Methode, in der du das XML-File verändern willst, schreibst du das von Kulabac rein und passt es für dich an.
Bei meiner Klasse übergibst du nichts dem Konstruktor.
Code:
XMLOutputter outputter  = new XMLOutputter();

Ohne meine Klasse hättest du Kulabacs Code sowieso nicht nehmen können, weil Java von Haus aus diese Klasse gar nicht zur Verfügung stellt. JDOM hat eine solche Klasse.

Ich hoffe das hilft dir weiter.

MFG

zEriX
 
So hatte ich das auch gemacht, aber daran liegt es wohl nicht.

Ich bekomme in dieser Zeile
Code:
DocumentBuilder builder = factory.newDocumentBuilder();
immer im Debugger die Fehlermeldung "not available [local variables unavailable]". Weiss jemand woran das liegt, oder ist das daraus nicht zu erkennen?
 
Was passiert denn, wenn du das Programm durchlaufen lässt? Also ohne Debugger.
 
Er bringt eine NullPointerException, da die Datei nicht gefunden wird. Durch das Reingehen mit dem Debugger habe ich dann diese Stelle ausfindig gemacht.

Die Datei wird also nicht gefunden, weil der Dateiname aus der TableConfig nicht ausgelesen wird.
 
Zuletzt bearbeitet:
In meiner Methode readTableConfig() (siehe auch ganz oben) wird die xml-Datei geparst, um dort bestimmte Daten auszulesen, nämlich tableName, title und color. tableName benötige ich, um den Dateiname der auszulesenden Datei zu erhalten. Der Fehler tritt also beim parsen der Datei auf, in diesem Codeabschnitt.
Code:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("tableConfig.xml"));
 
Zurück