# Daten aus DB in XML-Datei schreiben



## BlazZ (17. August 2009)

Hallo zusammen ich hoffe, dass ihr mir ein wenig helfen könnt.

Also Ausgangspunkt ist eine mysql datenbank auf einem webserver. Dieser enthält daten

Titel, Vorname, Name, Bild, Raum, Telefonnummer. Soweit so gut. Ich möchte die in der Datenbank gespeicherten Daten automatisch in eine XML Datei schreiben.

Diese sollte nachher diese form in etwa haben:

```
<personen>
        <person>
                    <titel>Herr</titel>
                    <vorname>Max</vorname>  
                    <name>Mustermann1</name>
                    <Bild>/img/mustermann.jpg"</Bild>
                    <Raum>100</Raum>
                     <tel>0123451234</tel> 
                     .............
         </person>
</personen>
```

Die Verbindung zur DB aufbauen geht ja noch, aber wie stelle ich die Daten mit Hilfe vonStax so dar, dass die xml Datei nachher so aufgebaut ist 3wie oben zu lesen?

So habe ich die verbindung zur db aufgebaut. Nur was muss ich nun tun ?



> import java.sql.*;
> import java.io.*;
> import java.util.*;
> 
> ...



Danke für eure hilfe


----------



## kuddeldaddeldu (17. August 2009)

Hi,

das hier ist das Java*script*-Forum. 
Bitte am besten einen Moderatoren, Deinen Thread zu verschieben.

LG


----------



## BlazZ (18. August 2009)

ups, du hast völlig recht, da habe ich mich aber schon dämlich bei der Kategorisierung angestellt. 

Nun gut, ich hoffe das man mir hier weiterhelfen kann ^^


----------



## zeja (18. August 2009)

Was willst du denn mit den XML-Daten machen? Musst du die später wieder einlesen?


----------



## BlazZ (18. August 2009)

Ich habe falsch herum angefangen. also ich habe bereits eine website erstellt, die die xml datei einliesst und darstellt (unter anderem auch tooltip etc.)

Nur was ich nicht wirklich hinbekomme ist die daten aus der mysql db zu selektieren und dann in eine xml datei zu schreiben. ich habe bereits versucht mit XMLOutputFactory eine normale xml datei zu erzeugen. Das klappt, nur wie schreibe ich daten von der mysql db in die xml datei. es ist ja ein unterschied ob man eine datei manuell hinzufügt oder diese aus der db einliesst.


```
import java.io.*;

public class XMLCreater{

  public void main(String[] args){  
       XMLOutputFactory factory = XMLOutputFactory.newInstance();
       XMLStreamWriter writer = factory.createXMLStreamWriter(new FileOutputStream("person.xml"));
 
writer.writeStartDocument();
 writer.writeStartElement("Personen");
    writer.writeStartElement("Person");
     writer.writeAttribute("vorname","Max");
     writer.writeAttribute("name","Mustermann");
     writer.writeEndElement();
   writer.writeEndElement();
  writer.writeEndDocument();
writer.flush();
writer.close();
```

so erzeugt man ja ein xml datei mit xmloutputfactory, nur wie muss ich es gestalten, dass die datenbankdaten eingelesen werden.

Ich bin dankbar für jede hilfe ^^


----------



## zeja (18. August 2009)

Du liest die Daten der Datenbank in einer Schleife aus

```
while(resultSet.next()) {
    final String vorname = resultSet.get("vorname");
    final String nachname = resultSet.get("nachname");
}
```

Wieso greift die Webseite denn nicht direkt auf die Datenbank zu?


----------



## BlazZ (18. August 2009)

mein prof liebt es anspruchsvolle hausaufgaben zu verteilen und ich hatte ne zu große kappe. das habe ich nun davon ^^

Auf jeden Fall danke für die Antwort, ich werde es direkt einmal ausprobieren ^^


----------



## BlazZ (19. August 2009)

so hallo zusammen, ich brauche leider nochmals eure hilfe.

Ich habe das ganze nun mit einem BufferedWriter umgesetzt und lese die Daten ein.


```
import java.sql.*;
import java.io.*;

public class createXML {
	public static void main(String[] args)throws Exception {
		
		Connection con = null;
		
		try {
			String url = "jdbc:mysql://localhost/dbname";
			String driver = "com.mysql.jdbc.Driver";
			String user = "";
			String password = "12345678";

			Class.forName(driver);

			con = DriverManager.getConnection(url, user, password);
			
			Statement stmt = con.createStatement();
			String sql = "Select* from dozenten inner join lehrgebiete on dozenten.lid = lehrgebiete.lid";
			ResultSet rs = stmt.executeQuery(sql);
			
			BufferedWriter bw = new BufferedWriter (new FileWriter("person.xml"));
			bw.write("<?xml version=\"1.0\"?>\n\r");	
			bw.write("<Personen>");
			while (rs.next()){
				bw.write("<Person>");
				bw.write("<titel>");
				String titel = rs.getString("Titel");
				bw.write(titel);
				bw.write("</titel>"); 
				bw.write("<vorname>");
				String vorname = rs.getString("Vorname");
				bw.write(vorname);
				bw.write("</vorname>");
				bw.write("<nachname>");
				String nachname = rs.getString("Nachname");
				bw.write(nachname);
				bw.write("</nachname>"); 
				bw.write("</Person>\n\r");		
			}				
			bw.write("</Personen>\n\r");
			
			bw.close();
			rs.close();
			stmt.close();

		}
		finally {
			try {
				if (con != null)
					con.close();
			}
			catch (Exception e) {
				System.err.println(e);
			}
		}
	}
}
```

Leider bekomme ich noch diese Fehlermeldung:



> Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
> at java.net.URLClassLoader$1.run(Unknown Source)
> at java.security.AccessController.doPrivileged(Native Method)
> at java.net.URLClassLoader.findClass(Unknown Source)
> ...



Wo liegt mein Fehler


----------



## zeja (19. August 2009)

Du musst dir von der mysql Seite den mysql Java Connector runterladen und in deinen Classpath legen. Dort ist der Treiber für die Verbindung zur MySQL Datenbank aus Java heraus enthalten.


----------



## BlazZ (19. August 2009)

Hi,

vielen Dank für deine Hilfe. 

Ich habe Connector/J für meine MYSQL DB heruntergeladen.

Ich selber arbeite erstmals mit Eclipse und Ant. Irgendwas scheine ich immer noch falsch zu machen, denn ich bekomme folgende Fehlermeldung.


```
Buildfile: C:\homework\ProfessorenInformationsSystem\build.xml
run:
      Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
      	at java.net.URLClassLoader$1.run(Unknown Source)
      	at java.security.AccessController.doPrivileged(Native Method)
      	at java.net.URLClassLoader.findClass(Unknown Source)
      	at java.lang.ClassLoader.loadClass(Unknown Source)
      	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
      	at java.lang.ClassLoader.loadClass(Unknown Source)
      	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
      	at java.lang.Class.forName0(Native Method)
      	at java.lang.Class.forName(Unknown Source)
      	at createXML.main(Unknown Source)
      Java Result: 1
BUILD SUCCESSFUL
Total time: 422 milliseconds
```

Dabei habe ich unter dem JAVA Build Path die mysql-connector-java-5.1.8-bin hinzugefügt. Irigendwie stelle ich mich äußerst blöd an. Zusätzlich habe ich die Klassen eigentlich hinzugefügt:

 hier ein screenshot:

http://img194.imagevenue.com/img.php?image=86889_561_122_497lo.JPG

Was mache ich noch falsch ?

Danke für eure HIlfe


----------



## benhaze (19. August 2009)

schau dir doch mal DOM4J an, um z.B XML-Dateien zu erstellen/lesen/ändern.

http://www.dom4j.org/dom4j-1.6.1/guide.html


----------



## zeja (19. August 2009)

Wenn du mit Ant baust, hat der eclipse classpath keinen Einfluss darauf. Schau mal in der Ant Dokumentation. Ich nehmen an du benutzt den java Task? Dort gibt es Beispiele wie man den classpath angeben muss. Ansonsten poste mal wie deine build.xml ausschaut.

Allerdings musst du unter eclipse zum starten auch kein Ant verwenden. Mit Run As Java Application läuft das auch so.


----------



## BlazZ (19. August 2009)

Ich woltle es tatsächlich etwas professioneller gestalten mit Ant, obwohl ich eigentich davon nicht die große Ahnung habe. Deswegen nutze ich es. 

Also meine Applikation läuft tatsächlich. Danke erst einmal dazu. Jetzt würde ich nur noch gerne das ganze mit Ant verfollständigen.



> <project name="ProfessorenInformationsSystem" default="compile" basedir=".">
> <target name="prepare">
> <mkdir dir="build"/>
> </target>
> ...



ich habe einen ordner jdbc erstlelt und die mysql-connector-java-5.1.8-bin dort reingestellt. Diesen haben ich als classpath mitgegeben.

Leider läuft es aber immer noch nicht. Irgendeine Idee was ich noch falsch mache ?


----------



## zeja (19. August 2009)

Nenn den Ordner mal am Besten lib. So macht man das meist in Java-Projekten und schmeißt da alle Jars rein die man zusätzlich benötigt.

Versuch mal das entsprechend:


```
<target name="run" description="Run program">
  <java classname="createXML" fork="true">
    <classpath>
        <fileset dir="lib">
          <include name="**/*.jar"/>
        </fileset>
    </classpath>
  </java>
</target>
```

Siehe auch
http://ant.apache.org/manual/CoreTasks/java.html
und dort dem Path Like Structure Link bei Classpath folgen.


----------



## BlazZ (19. August 2009)

Nochmals vielen Dank. Also ich habe das ganze mal durchgespielt und nach der Anpassung bekomme ich den folgenden Fehler


```
java.lang.NoClassDefFoundError: createXML
      Caused by: java.lang.ClassNotFoundException: createXML
      	at java.net.URLClassLoader$1.run(Unknown Source)
      	at java.security.AccessController.doPrivileged(Native Method)
      	at java.net.URLClassLoader.findClass(Unknown Source)
      	at java.lang.ClassLoader.loadClass(Unknown Source)
      	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
      	at java.lang.ClassLoader.loadClass(Unknown Source)
      	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
      Could not find the main class: createXML.  Program will exit.
      Exception in thread "main" 
      Java Result: 1
```

createXML.class wird aber in /build/ generiert.


----------



## BlazZ (19. August 2009)

wie sagt man so schön, ich stehe heute irgendwie aufm schlauch und nichts geht. 

Also ich habe mich nochmal mit Ant ein wenig beschäftigt und nachträglich Ant einzeln heruntergeladet. Das kuriose ist, Ant hat unter Eclipse ja auch so funktioniert. Eigentlich kann es daran ja nicht liegen. . Aber da ich mir nicht mehr anders zu helfen weiß ...

Also habe ich nochmal Ant heruntergeladen und %Ant_Home% festgelegt. %JAVA_HOME% hatte ich vorher schon festgelegt. Als KLassenpfade habe ich %ANT_HOME%/bin und %JAVA_HOME%/bin hinzugefügt. Aber auch das hat nicht geholfen. Ich verstehe es so, dass die compilierte Klasse -> XMLcreate.class nicht gefunden wird. Deswegen habe ich sogar den Klassenpfad in den Umgebungsvariablen mal an .... /build/ angepasst, aber auch das hat nicht geholfen. Das liegt wohl daran, dass Ant garnicht darauf zugreift. 

Ich weiß wirklich nicht mehr weiter und wäre für jede Hilfe dankbar ... Danke


----------



## zeja (19. August 2009)

Ja richtig. Du musst schon noch das Verzeichnis wohin du compilierst (build) hinzufügen.

Sollte so gehen:
<pathelement location="build"/>

Steht so zumindest in dem Link den ich dir im letzten Post gegeben hatte.


----------



## BlazZ (20. August 2009)

Hi,

erst einmal vielen Dank, du hast mir sehr geholfen. Es klappt jetzt ^^.

Ich habe nur ein letztes kleines Problem. Ich möchte keine Tag einlesen, wo keine Daten drin enthalten sind. in der XML Datei sollen hinterher nicht solche tags :</img src=" "/> sondern garnicht erst angezeigt werden.


```
import java.sql.*;
import java.io.*;

public class createXML {
	public static void main(String[] args)throws Exception {
		
		Connection con = null;
		
		try {
			String url = "jdbc:mysql://localhost/hsnr";
			String driver = "com.mysql.jdbc.Driver";
			String user = "root";
			String password = "jinzhosse";

			Class.forName(driver);

			con = DriverManager.getConnection(url, user, password);
			
			Statement stmt = con.createStatement();
			String sql = "Select* from dozenten inner join lehrgebiete on dozenten.lid = lehrgebiete.lid";
			ResultSet rs = stmt.executeQuery(sql);
			
			BufferedWriter bw = new BufferedWriter (new FileWriter("lehrende.xml"));
			bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\r");	
			bw.write("<lehrende>");
			while (rs.next()){
				bw.write("<person>");
				bw.write("<titel>");
				String titel = rs.getString("Titel");
				bw.write(titel);
				bw.write("</titel>"); 
				bw.write("<vorname>");
				String vorname = rs.getString("Vorname");
				bw.write(vorname);
				bw.write("</vorname>");
				bw.write("<nachname>");
				String nachname = rs.getString("Nachname");
				bw.write(nachname);
				bw.write("</nachname>"); 
				bw.write("<lehrgebiet>");
				String lehrgebiet = rs.getString("Lehrgebiet");
				bw.write(lehrgebiet); 
				bw.write("</lehrgebiet>"); 
				bw.write("<website>");
				String website = rs.getString("Website");
				bw.write(website); 
				bw.write("</website>"); 
				bw.write("<room>");
				String room = rs.getString("Buero");
				bw.write(room); 
				bw.write("</room>"); 
				bw.write("<email>");
				String email = rs.getString("Email");
				bw.write(email);
				bw.write("</email>"); 
				bw.write("<tel>");
				String telefon = rs.getString("Telefon");
				bw.write(telefon);
				bw.write("</tel>"); 
				bw.write("<fax>");
				String fax = rs.getString("Fax");
				bw.write(fax);
				bw.write("</fax>"); 
				bw.write("<img src='");
				String img = rs.getString("Img");
				bw.write(img);
				bw.write("'/>"); 
				bw.write("</person>\n\r");		
			}				
			bw.write("</lehrende>\n\r");
			
			con.close();
			bw.close();
			rs.close();
			stmt.close();

		}
		finally {
			try {
				if (con != null)
					con.close();
			}
			catch (Exception e) {
				System.err.println(e);
			}
		}
	}
}
```

Ich lese ja die Daten aus dem Resultset aus. und schreibe vorher die tags für die XML Datei. Mit einer IF-Abfrage müsste das doch irgendwie zu realisieren sein. 


Ich hatte an eine eine If abfrage gedacht:



> if rs.getString("Img") =null then doNothing und Springzumnächsten Tag..



Ich habe mal wieder viel nachgelesen aber nichts gefunden. Habt ihr vielleicht eine idee


----------



## zeja (20. August 2009)

Wie wärs mit:


```
private void addTag(BufferedWriter bw, String tagName, String value) {
   if(value != null){
      bw.write("<"+tagName+">");
      bw.write(value);
      bw.write("</"+tagName+">");
   }
}
```


```
addTag(bw,"titel",rs.getString("titel"));
```


----------



## benhaze (20. August 2009)

benhaze hat gesagt.:


> schau dir doch mal DOM4J an, um z.B XML-Dateien zu erstellen/lesen/ändern.
> 
> http://www.dom4j.org/dom4j-1.6.1/guide.html



Davon scheinst du nicht viel zu halten.....?
Bist du dir sicher das du dein XML-Dok wirklich *mit der Hand am Arm* selber stricken willst?


----------



## zeja (20. August 2009)

Für ne Hausaufgabe reichts das mal eben so zu machen 

Wenn dann würde ich eher XStream verwenden. Dann muss man gar nichts mit XML zu tun haben.


----------



## BlazZ (20. August 2009)

Danke für eure Antworten. 

Ich wollte das ganze ursprünglich mit SAX realisiern, hatte aber Probleme damit die Daten aus der Datenbank an Sax zu übergeben und nachher auszugeben.


----------



## benhaze (20. August 2009)

zeja hat gesagt.:


> Für ne Hausaufgabe reichts das mal eben so zu machen
> 
> Wenn dann würde ich eher XStream verwenden. Dann muss man gar nichts mit XML zu tun haben.



Mit X-Stream ist es auch OK.

Gibt dir dein Prof keinen heftigen Punkteabzug, wenn er sieht wie du XML-Dokumente per Hand zusammenstrickst?
Da kann dich ANT auch nicht mehr raushauen....


----------



## BlazZ (20. August 2009)

Das wird sich noch herausstellen. Mal abgesehen davon ist das nur ein teil der Hausarbeit. Denn ich lese die Daten nachher auch wieder aus und stelle sie mit xsl dar. 

Vielleicht wage ich mich ja noch an SAX ran, aber ich muss heute fertig werden ^^


----------



## zeja (20. August 2009)

Mit XStream hättest du ja beides. Sowohl auslesen als auch schreiben und das ganze auch noch in schönen Java-Objekten. Gucks dir doch mal kurz an: xstream.codehaus.org


----------



## BlazZ (20. August 2009)

sieht interessant aus, ich habe aberimmer das gleiche Problem. Wie bekomme ich die Daten aus der Datenbank übertragen außer mit 

String resultat = rs.getString("Abfrage") 

also wie sage ich XSTREAM nimm die Daten aus der DB ... Damit tue ich mich immer sehr schwer ^^


----------



## benhaze (20. August 2009)

Bau dir eine Klasse, die die Informationen aus einer Row beinhaltet.
Dann das Object mit X-Stream in ein XML-Dok umwandeln.
oder mit Dom4J:


```
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class Foo {

    public Document createDocument() {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement( "root" );

        Element author1 = root.addElement( "author" )
            .addAttribute( "name", "James" )
            .addAttribute( "location", "UK" )
            .addText( "James Strachan" );
        
        Element author2 = root.addElement( "author" )
            .addAttribute( "name", "Bob" )
            .addAttribute( "location", "US" )
            .addText( "Bob McWhirter" );

        return document;
    }
}
```


----------



## BlazZ (20. August 2009)

Auch auf die Gefahr hin mich blöd anzustellen, aber verstehe ich es richtig.

Du meinst ich soll die Daten lieber manuell in dieser Row Datei eingeben und nachher nur umwandeln  

Genau das möchte ich gerade vermeiden Ich möchte unbedingt mit einer DB arbeiten. Neue Mitarbeiter sollen einfach nur noch über ein insert hinzugefügt werden können, ohen das jemand in den Daten nachher noch arbeitet. Deswegen lese ich die Daten ja aus der DB aus.

Trotzdem danke für den Tipp


----------



## benhaze (20. August 2009)

Nein.
Du erstellest eine Klasse.
Meinetwegen Person.
Diese Klasse beinhaltet alle Felder aus der DB.
Bsp;
String getName()
setName(String name)
int getAlter()
setAlter(int alter)

Dann holst du dir die Daten aus der DB und erstellst analog zu einer Row aus der DB ein Person Object:
Person p = new Person();
p.setName(rs.getString("name));
p.setAlter(rs.getInteger("alter));

u.s.w

nun hast du deine Row schonmal in einem Objekt.
Diese Objekt kannst du  nun an x-Stream übergeben und X-Stream baut dir daraus ein XML Dokument.

oder mir DOM4J (allerdings musst du dann selber aus dem entspr. Objekt ein XML-Dok erzeugen)


----------

