# Text to XML



## Alessandro M (18. Feb 2008)

Hallo zusammen,

ich muss für ein Studium-Projekt dafür sorgen, dass ein Text-File mit Java in ein XML-File umgewandelt wird.
Die Text-Datei hat folgende Struktur (Ausschnitt):


```
## Kommentare
## Kommentare
SET [b]Variable1 [/b][b]12[/b]
## Kommentare
SET [b]Variable2 [/b][b]abc[/b]
## SET Variable3 0
## Kommentare
SET Variable4 1
SET Variable5 345
## Kommentare
## Kommentare
## Kommentare
## Kommentare
```

Wichtig sind die Zeilen, die mit "SET" beginnen und auch die auskommentierten Zeilen, die mit "SET" beginnen. Alle anderen auskommentierten Zeilen sind nicht von Bedeutung.

Das XML-File sollte ungefähr diese Form haben:

<attribute name="*Variable1 *" type="textfield" preferred-width="40" help="no" tooltip="no" max-chars="255" invalid-chars=" " value="*12*"></attribute>
<attribute name="*Variable2 *" type="textfield" preferred-width="40" help="no" tooltip="no" max-chars="255" invalid-chars=" " value="*abc*"></attribute>

usw.

Wie kann ich mit Java die Text-Datei Zeile für Zeile auslesen und dementsprechend daraus ein XML-Item erzeugen?
Da ich mich in diesem Fach noch nicht so gut auskenne, wäre es toll, wenn mir jemand ein paar Hilfestellungen geben könnte. Evtl. hat jemand von euch schon mal was damit gemacht und könnte mir den Code posten!?

Vielen Dank im Voraus für die Hilfe.

Mit freundlichen Grüßen
Alessandro M.


----------



## ARadauer (18. Feb 2008)

sorry aber das ist schon sehr wenig eigeninitative.


> mit Java die Text-Datei Zeile für Zeile auslesen


versuch, das mal selber, dann helf ich dir mit den weiteren schritten


----------



## Alessandro M (18. Feb 2008)

Da fangen bei mir ja schon die Schwierigkeiten an :-/

Folgenden Code habe ich bisher:


```
package Pack;
import java.io.*;
public class txt2xml {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	      String zeile="";
	      try {
	        BufferedReader b = new BufferedReader (new FileReader("C:\\test.txt") );
	        while( (zeile = b.readLine()) != null ) // liest zeilenweise aus Datei
	        { 
	          if (zeile=="## COMMON SETTINGS")
	          {
	        	  System.out.println("test");
	          }
	          System.out.println(zeile); // Ausgabe zeilenweise

	        }
	        b.close();
	      }
	      catch (IOException e) {
	        System.out.println("Fehler: "+e.toString());
	      }
	}

}
```

In meiner Text-Datei habe ich auf jeden Fall die Zeile "## COMMON SETTINGS" stehen, allerdings erfolgt hier nie eine Ausgabe "test" obwohl er mir in der Zeile drunter die Ausgabe 
	
	
	
	





```
System.out.println(zeile);
```
 ordentlich macht!?

Ich möchte auf keinen Fall, dass hier jemand für mich das Projekt realisiert... ein paar Hilfestellungen wären aber von großem Vorteil, da ich - wie erwähnt - noch nicht so fit in der Sache bin.

Danke!


----------



## maki (18. Feb 2008)

MIt == vergleicht man Referenzen oder primitive Typen.. was du brauchst ist equals.


----------



## byte (18. Feb 2008)

Überleg erstmal, welche XML-Bibliothek Du verwenden willst und lies Dich dort in die API ein. Ich kann Dir Stax empfehlen.


----------



## Alessandro M (18. Feb 2008)

Danke @ maki  

Damit ist mir schon mal geholfen 

ich schau mir jetzt mal STAX an


----------



## Alessandro M. (18. Feb 2008)

@ARadauer:

Den einen Schritt habe ich schon mal realisiert... Hast du denn eine Idee wie ich nun aus der TXT eine XML erstelle?

Danke und viele Grüße
Alessandro M.


----------



## Faruun (19. Feb 2008)

Wenn Du die Zeilen eingelesen hast, dann musst Du Dir den Teil in Variablen speichern, der für Dich interessant ist.

Wenn ich das richtig verstanden habe, suchst Du zunächst alle Zeilen, die ein SET beinhalten. Inhaltlich kannst Du einen String mit contains(String) auf ein bestimmten Teil durchsuchen.

Speicher Dir die Strings, die diesen Teil haben am besten in eine Liste, damit Du sie zur Erzeugung der xml im Zugriff hast.

Wenn das klappt, sehen wir weiter ;-)

Gruß,
Faruun


----------



## Guest (19. Feb 2008)

So, das mit der Liste habe ich nun geschafft  Danke schon mal für den Tip!


```
LinkedList<String> parameter = new LinkedList<String>(); // Liste, die mit Parametern erweitert wird
BufferedReader b = new BufferedReader (new FileReader(xmlpfad) );
while( (zeile=b.readLine() )!= null) // liest zeilenweise aus Datei
{ 
  if (zeile.contains(key_parameter)) // Suchen von SET-Parametern
  {
    System.out.println(zeile); // Ausgabe zeilenweise
    parameter.add(zeile);
  }       	
}
b.close();
```

Folgende Ausgabe erhalte ich:


```
SET VAR1 135.64.235.152
SET VAR2 abc
## SET VAR3 abc
SET VAR4 1
SET VAR5 0
```


obwohl die Text-Datei so aussieht:  


```
## COMMON SETTINGS
SET VAR1 135.64.235.152
## 46xx SETTINGS
SET VAR2 abc
## SET VAR3 abc
## COMMON SETTINGS
SET VAR4 1
## 46xx SETTINGS
SET VAR5 0
```

Wie erzeuge ich nun aus meiner Liste ein XML-File, das folgendermaßen aussieht:


```
<attribute name="VAR1" type="textfield" preferred-width="40" help="no" tooltip="no" max-chars="255" invalid-chars=" " value="135.64.235.152" active="true"></attribute>
<attribute name="VAR2" type="textfield" preferred-width="40" help="no" tooltip="no" max-chars="255" invalid-chars=" " value="abc" active="true"></attribute> 
<attribute name="VAR3" type="textfield" preferred-width="40" help="no" tooltip="no" max-chars="255" invalid-chars=" " value="abc" active="false"></attribute>
```

usw.... ??? 

Über ein paar Hilfestellungen dazu würde ich mich sehr freuen...

Vielen Dank im Voraus.

Grüße
Alessandro


----------



## Faruun (19. Feb 2008)

Huhu,

sehr schick soweit. :applaus: 

Also ich würde wie folgt weiter vorgehen:

Ich würde mir JDOM anschauen (www.jdom.org). Das bietet Dir die Möglichkeit allerhand mit xml-Dateien zu tun. Zu dem vorher vorgeschlagenen Stax kann ich leider gar nichts sagen ... kenn ich nicht.

Wenn Du Dich für JDOM entscheidest, funktioniert das Ganze ungefähr so:

1. Erstelle ein Document
2. Hänge ein root-Element daran
3. Erstelle in einer Schleife weitere Elemente als Child vom root-Element, solang Du Elemente in Deiner Liste hast (Iteration)
4. Für jedes Element gilt dann: Nimm das aktuelle Element Deiner Liste, suche Dir die Infos raus und füge diese als Attribut an das xml-Element
5. Schreibe das xml-Document in eine Datei

Das wars.

Gibt sicher auch andere Möglichkeiten, aber so würde ich es machen. Vielleicht bietet Dir hier noch jemand eine andere, schicke, einfachere Variante an.

Bei Fragen, Fragen ;-)

Faruun


----------



## byte (19. Feb 2008)

(J)DOM ist sinnvoll, wenn man die komplette Baumstruktur im Speicher halten will, ist aber ansonsten speicherhungrig und nicht sehr performant. Da die Datei in diesem Fall sowieso zeilenweise eingelesen wird, kann man auch direkt XML per Stream rausschreiben. Das geht mit Stax sehr gut und schnell.


----------



## Guest (20. Feb 2008)

Erstmal DANKE für die Infos...

Ich hab mir im Inet ein paar Infos geholt und es so verstanden, dass JDOM zwar speicheraufwendiger ist, aber man ständigen Zugriff auf die XML-Datei hat. Bei SAX hat man dies nicht, od?

Mir geht es um Folgendes: Nachdem ich meine TXT in eine XML Datei umgewandelt habe, will ich über die GUI Änderungen vornehmen, die zunächst in die XML-Datei und anschließend in der TXT-Datei geändert werden.

Ist es also hier nicht ratsam mit DOM zu arbeiten, da ich ständig Änderungen in der XML-Datei vornehmen muss?


----------



## byte (20. Feb 2008)

In diesem Fall macht DOM natürlich Sinn. Du kannst dann über die Baumstruktur auf die XML-Elemente zugreifen. Am besten mal einen Blick auf www.jdom.org werfen.


----------



## Ale M. (20. Feb 2008)

Eine weitere Frage:

Wie kann ich einen String folgendermaßen aufspalten:

```
SET VAR3 abc
```
soll zu 

```
VAR3
```
werden...

*Achtung*: Die Bezeichnung VAR3 ist hier ein Beispiel. Es könnte auch TESTXXY heißen..., d.h. die Länge dieses Teilstrings ist mir nicht bekannt.

Wie kann ich also den Teilstring zwischen dem ersten und zweiten Leerzeichen ermitteln? 

Ich weis, dass diese Frage eigentlich nicht in diesen Bereich gehört, allerdings ist sie Teil des Projektes und das würde mir helfen hier die entsprechende Info zu erhalten...

Vielen Dank!


----------



## byte (20. Feb 2008)

Da gibts viele Möglichkeiten. Guck Dir an was die Klasse String zu bieten hat: http://java.sun.com/javase/6/docs/api/java/lang/String.html

Du kannst es z.b. mit split() machen oder mit substring() / indexOf() oder mit Regex.


----------



## Faruun (21. Feb 2008)

Wie byto schon sagte: substring() / indexOf() sind schön einfache Varianten, denk ich.

Regex ist ne tolle und sehr mächtige Sache, wenn man weiß was man tut. Es kann aber auch schnell sehr ausufernd und kompliziert werden. Wenn Du dich mit Regex auskennst, gehts aber an und für sich auch sehr schick.


----------



## Ale M. (22. Feb 2008)

Dankeschön, das Ganze habe ich nun erfolgreich mit split() implementiert! Tolle Hilfe, die hier angeboten wird...!

Zur weiteren Vorgehensweise:

Mittlerweile habe ich es geschafft, folgende XML-Datei zu generieren:


```
<xml version="1.0" encoding="utf-8"> 
	<group name="A"> 
		<subgroup name="a1> 
			<attribute name="abc" value="abc" active="true"></attribute> 
			<attribute name="def" value="123" active="false"></attribute> 
			<attribute name="ghi" value="0" active="false"></attribute> 
		</subgroup> 
		<subgroup name="a2"> 
			<attribute name="jkl" value="bla" active="true"></attribute> 
			<attribute name="mno" value="test" active="true"></attribute> 
		</subgroup> 
	</group> 
	<group name="B"> 
		<subgroup name="b1"> 
			<attribute name="pqr" value="1" active="true"></attribute> 
			<attribute name="stu" value="0" active="false"></attribute> 
		</subgroup> 
		<subgroup name="b2"> 
			<attribute name="vwx" value="xxx" active="true"></attribute> 
		</subgroup> 
	</group>
```

Der nächste schwierige Schritt besteht darin aus der XML-Datei dynamisch eine Oberfläche aufzubauen...
Kann ich hierzu ein paar Tips erhalten? Wäre toll, damit ich nicht planlos Zeit verschwende und von Anfang an den richtigen Weg einleite...

Folgendermaßen sollte der Aufbau der GUI funktionieren:

Das was unter GROUP steht sollte links im Menü auftauchen und die dazugehörigen SUBGROUPS mit Parametern rechts im Content-Bereich.

Die Grafik soll dies verdeutlichen:







Ich freue mich über eure Hilfestellungen! Danke im Voraus!


----------



## byte (22. Feb 2008)

Der nächste Schritt bestünde darin, dass Du erstmal zu der XML ein passendes Java-Datenmodell entwirfst. Du musst also die XML-Elemente und Attribute auf geeignete Java-Klassen abbilden. Passend dazu benötigst Du dann einen Mechanismus, der Dir die Daten einliest und daraus die Java-Objekte erzeugt und bei Bedarf auch die Java-Objekte wieder in XML zurückschreibt. Wenn Du damit fertig bist, kannst Du dann den nächsten Schritt gehen und aus diesen Objekten die GUI generieren.

Es bietet sich an, hier zunächst mal zu schauen, welche Frameworks Dich dabei unterstützen können. Spontan fällt mir da JAXB ein. Damit kannst Du XML mit Java-Objekten binden. Du kannst auch direkt die Klassenstruktur erzeugen lassen. AFAIK musst Du dazu aber erstmal ein XML-Schema für Deine XML-Dateien schreiben. Sollte aber in diesem Fall recht einfach sein.


----------



## Faruun (22. Feb 2008)

Huhu,

Glückwunsch zum Fortschritt.

Ein paar Fragen vorab:

Hast Du schon eine GUI oder willst Du die erst bauen?
Soll das Ganze in eine Art Explorersicht gebaut werden? (->Baumstruktur?)

Gruß,
Faruun


Edith sagt: byto war schneller ;-)


----------



## Ale M. (22. Feb 2008)

@byto: 

Nein, ich habe noch keine GUI gebaut - deswegen wende ich mich erstmal an das Forum... Will ja nicht die GUI bauen, die ich dann evtl. nicht verwenden kann... Wollte mir deshalb hier ein paar Infos holen, bevor ich loslege 

Ja, in einer Art Explorer-Ansicht wäre es optimal...  Danke byto!


----------



## Guest (22. Feb 2008)

Sorry...

ich meinte Faruun  bzw. Danke an euch beiden!


----------



## Ale M. (26. Feb 2008)

Hat denn keiner mehr nützliche Tips wie ich aus den Daten aus der XML-Datei meine GUI aufbauen kann?

Das mit der typischen Win-Explorer Struktur / Ansicht hört sich auf jeden Fall vorteilhaft an..

Also ungefähr eine solche GUI:






aus sochen Daten aus der XML-Datei:


```
<xml version="1.0" encoding="utf-8">
   <group name="A">
      <subgroup name="a1>
         <attribute name="abc" value="abc" active="true"></attribute>
         <attribute name="def" value="123" active="false"></attribute>
         <attribute name="ghi" value="0" active="false"></attribute>
      </subgroup>
      <subgroup name="a2">
         <attribute name="jkl" value="bla" active="true"></attribute>
         <attribute name="mno" value="test" active="true"></attribute>
      </subgroup>
   </group>
   <group name="B">
      <subgroup name="b1">
         <attribute name="pqr" value="1" active="true"></attribute>
         <attribute name="stu" value="0" active="false"></attribute>
      </subgroup>
      <subgroup name="b2">
         <attribute name="vwx" value="xxx" active="true"></attribute>
      </subgroup>
   </group>
```

Vielen Dank für eure Antworten!

Gruß


----------



## Faruun (26. Feb 2008)

Hast Du Dich denn schonmal mit swing etc. beschäftigt?


----------



## Ale M (26. Feb 2008)

Hi,

ja- ich hab mich in den Bereich eingelesen, aber ich bräuchte einfach nur ein kleines Beispiel (bezogen auf mein Fall), damit ich schnellstmöglich den Umgang mit diesem Werkzeug erlerne...

Hast Du denn schon mal damit gearbeitet? Wenn ja, könntest Du mir ein Code-Beispiel (bezogen auf mein Fall) posten?

Das würde mich wirklich freuen...

Danke und Grüße
Ale


----------



## byte (26. Feb 2008)

Erwartest Du jetzt tatsächlich, dass sich jemand die Arbeit macht und Dir Code zu Deiner Aufgabe schreibt?

Die Vorgehensweise habe ich doch schonmal beschrieben: Wenn Du aus aus den XML-Daten Java-Objekte generiert hast, dann musst Du über diese Struktur iterieren und daraus die Swing-Komponenten erzeugen. Das wird ungefähr so aussehen, dass Du für jede Subgroup ein JPanel erzeugst und diese je nach Auswahl der Group untereinander anzeigst (anordnen der JPanels mit einem LayoutManager, z.B. BoxLayout). Dann iterierst Du für jede Subgroup über die Attribute und generierst in diesem JPanel die nötigen Komponenten (JLabel für den Attributnamen, JTextField für den Attributwert und JComboBox für das Active-Attribut). Anordnung dieser Komponenten im JPanel wiederum per LayoutManager.

Hier noch das Swing-Tutorial mit allen nötigen Informationen zur GUI-Programmierung:
http://java.sun.com/docs/books/tutorial/uiswing/


----------



## Faruun (27. Feb 2008)

Ich denke auch, dass der Weg eher andersrum laufen soll und auch wird. Nicht wir programmieren Dir die Oberfläche, sondern Du machst das und bei *konkreten* Fragen können wir unterstützen.


----------

