# CSV Datei einlesen und verarbeiten



## DBR89 (30. Nov 2010)

Hi Leute,

ich arbeite gerade an einem Projekt, welches die Zellen der Deutschen telekom auf einer Deutschlandkarte darstellt.
Hierzu ist es nötig, dass ich ein kleines Tool schreibe, welches eine CSV Datei einließt und später als GPX Datei abspeichert. Das ganze soll so aussehen, das folgende Parameter eingelesen werden sollen:


```
Description	Comment						Name					Latitude	Longitude	Releasecause	Sum
BTSSM	Berlin/GueterBhf-Schoenholz 315	Cell-ID: 43000043		52,571111	13,383056	882				1524
BTSSM	Lünen 0							Cell-ID: 43000188		51,608333	7,524444	872				678
```

Diese Daten sollen dann folgender Maßen verpackt werden:

```
<gpx

<wpt lat="52.571111000" lon="13.383056000">
  <name>Cell-ID: 43000043</name>
  <cmt>BTSSM</cmt>
  <desc>Berlin/GueterBhf-Schoenholz 315
  Releasecause: 0B1B
  Sum: 1524</desc>
</wpt>
</gpx>
```

Dazu habe ich folgendes schon geschrieben: 

Einlesen der CSV Datei
Speichern in einem Array
jetzt will ich das ganze aber in das oben angegebene Format packen, wie mache ich das am besten?
Hierzu müsste ich als erstes den String aufsplitten denke ich.
Zur Hilfe hier mal mein Quellcode:
[Java]
public static void main(String[] args) {

	    // Einlesen des Files und spliten
	    FileReader myFile = null;
	    BufferedReader buff = null;
	    final List<String> lines = new ArrayList<String>();

	    try {
	        myFile = new FileReader("test.csv");
	        buff = new BufferedReader(myFile);
	        String line;
	        while ((line = buff.readLine()) != null) {
	           // System.out.println(line); // kontrolle was eingelesen

	            lines.add(line);
	        }
	    } catch (IOException e) {
	        System.err.println("Error2 :" + e);
	    } finally {
	        try {
	            buff.close();
	            myFile.close();
	        } catch (IOException e) {
	            System.err.println("Error2 :" + e);
	        }
	    }

	    final String[][] valuesArray = new String[lines.size()][];
	    int cnt = 0;
	    for (final String line : lines) {
	        valuesArray[cnt++] = line.split(",");
	    }

	    // Ausgabe des Array
	    for (String[] arr : valuesArray) {
	        System.out.println(Arrays.toString(arr));
	    }
	}

[/Java]
Hoffe ihr könnt helfen.
Gruß Dennis


----------



## ARadauer (30. Nov 2010)

Was bedeutet den CSV?
line.split(","); macht bei einer CSV schon Sinn, nur ist dein Beispeil keine CSV... da ist nix mit einem Trennzeichen getrennt... sondern die Felder haben eine fixe länge...


----------



## Andi_CH (30. Nov 2010)

Die Frage war, wie bringt man Strings aus einem Array in eine XML Datei.
Das Einlesen ist ja erledigt ;-)


----------



## DBR89 (30. Nov 2010)

Andi_CH hat gesagt.:


> Die Frage war, wie bringt man Strings aus einem Array in eine XML Datei.
> Das Einlesen ist ja erledigt ;-)



so ist es.
Ausgabe meines Arrays:

1;BTSSM;Berlin/GueterBhf-Schoenholz 315;Cell-ID: 43000043;52,571111;13,383056;882;1524
1;BTSSM;Lünen 0;Cell-ID: 43000188;51,608333;7,524444;872;678

wie splitte ich das auf und kann das weiter verarbeiten?


----------



## André Uhres (30. Nov 2010)

Hallo Dennis,

versuch's mal so:


```
/*
 * ToXML.java
 */

import java.util.logging.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

public class ToXML {

    private StreamResult out;
    private TransformerHandler th;
    private AttributesImpl atts;
    String[] list = {
        "1;BTSSM;Berlin/GueterBhf-Schoenholz 315;Cell-ID: 43000043;52,571111;13,383056;882;1524",
        "1;BTSSM;Lünen 0;Cell-ID: 43000188;51,608333;7,524444;872;678"};

    public ToXML() {
        try {
            out = new StreamResult("data.xml");
            initXML();
            for (String str : list) {
                process(str);
            }
            closeXML();
        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(ToXML.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(ToXML.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void initXML() throws TransformerConfigurationException, SAXException {
        SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        th = tf.newTransformerHandler();
        Transformer serializer = th.getTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
        // pretty XML output:
        serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        th.setResult(out);
        th.startDocument();
        atts = new AttributesImpl();
        th.startElement("", "", "gpx", atts);
    }

    private void process(final String s) throws SAXException {
        String[] elements = s.split(";");
        atts.clear();
        atts.addAttribute("", "", "lat", "", "" + elements[4]);
        atts.addAttribute("", "", "lon", "", "" + elements[5]);
        th.startElement("", "", "wpt", atts);
        atts.clear();
        th.startElement("", "", "name", atts);
        th.characters(elements[3].toCharArray(), 0, elements[3].length());
        th.endElement("", "", "name");
        th.startElement("", "", "cmt", atts);
        th.characters(elements[1].toCharArray(), 0, elements[1].length());
        th.endElement("", "", "cmt");
        th.startElement("", "", "desc", atts);
        String desc = elements[2] + " Releasecause: " + elements[6] + " Sum: " + elements[7];
        th.characters(desc.toCharArray(), 0, desc.length());
        th.endElement("", "", "desc");
        th.endElement("", "", "wpt");
    }

    private void closeXML() throws SAXException {
        th.endElement("", "", "gpx");
        th.endDocument();
    }

    public static void main(final String args[]) {
        ToXML toXML = new ToXML();
    }
}
```

Gruß,
André


----------



## Andi_CH (30. Nov 2010)

DBR89 hat gesagt.:


> so ist es.
> Ausgabe meines Arrays:
> 
> 1;BTSSM;Berlin/GueterBhf-Schoenholz 315;Cell-ID: 43000043;52,571111;13,383056;882;1524
> 1;BTSSM;Lünen 0;Cell-ID: 43000188;51,608333;7,524444;872;678


Nur hast du den sicher nicht mit dem Code von oben eingelesen ;-)
Da kommt nämlich noch 

[BTSSM, , , Lünen, 0, , ,

raus


----------



## DBR89 (2. Dez 2010)

Hi Jungs, also bei mir funktioniert das Einlesen der CSV Problemlos, aber seis drum.
Ich habe noch eine Frage es geht um folgenden Code:

[Java]
final String[][] valuesArray = new String[lines.size()][];
	    int cnt = 0;
	    for (final String line : lines) {
	        valuesArray[cnt++] = line.split(",");
	    }

[/code]
Ich möchte jetzt das Array returnen, wie mache ich das jetzt am besten?

Gruß Dennis


----------



## Andi_CH (2. Dez 2010)

```
return valuesArray;
```
 ???:L???:L???:L


----------



## fastjack (2. Dez 2010)

Warum das Rad immer wieder neu erfinden? 

FlatPack - Introduction

:rtfm:


----------



## DBR89 (2. Dez 2010)

Andi_CH hat gesagt.:


> ```
> return valuesArray;
> ```
> ???:L???:L???:L




Type mismatch: cannot convert from String[][] to String ?

Hätte ich sonst auch so gemacht


-------------EDIT--------------
Problem gelöst


----------



## André Uhres (2. Dez 2010)

fastjack hat gesagt.:


> FlatPack - Introduction



Ich habe FlatPack jetzt ausprobiert. Ich konnte es nicht so ohne Weiteres installieren (man benötigt zusätzlich JDOM, SLF4J und einen SLF4J binding), aber es funktioniert jetzt und erleichtert so manches.

Gruß,
André


----------



## DBR89 (5. Dez 2010)

Hi Jungs, folgende Problematik:
Ich lese eine Datei ein und Speichere das Ganze in einem 2 Diemnsionalen Array. Die 1. Stelle gibt auskunft über die Anzahl der eingelesenen Spalten, die 2. Stelle des Arrays speichert den Inhalt der Spalte.
Zur weiteren Verarbeitung will ich das Array eindimensional zurückgeben. Wie kann ich das am Besten anstellen?
Für hilfe wäre ich euch sehr Dankbar.

```
public String[][] einlesen(){
    // Einlesen des Files und spliten
    FileReader myFile = null;
    BufferedReader buff = null;
    final List<String> lines = new ArrayList<String>();
 
    try {
        myFile = new FileReader("test.csv");
        buff = new BufferedReader(myFile);
        String line;
        while ((line = buff.readLine()) != null) {
           // System.out.println(line); // kontrolle was eingelesen
 
            lines.add(line);
        }
    } catch (IOException e) {
        System.err.println("Error2 :" + e);
    } finally {
        try {
            buff.close();
            myFile.close();
        } catch (IOException e) {
            System.err.println("Error2 :" + e);
        }
    }
 
    final String[][] valuesArray = new String[lines.size()][];
    int cnt = 0;
    for (final String line : lines) {
        valuesArray[cnt++] = line.split(",");
    }
    return valuesArray;
```


----------



## Andi_CH (6. Dez 2010)

Das geht nicht - ein 2D Array ist ein 2D Array und ein 1D Array ist etwas ganz anderes.

Wenn du eine Gerade willst nützt dir eine Fläche auch nichts


----------



## DBR89 (6. Dez 2010)

Kann ich nicht das 2D Array auslesen und in ein neues 1D Array abspeichern?

Wenn ja wie geht das?


----------



## Andi_CH (6. Dez 2010)

NEIN GEHT NICHT - schreib ich doch oben - ok, jetzt kannst du zum dritten mal fragen wie man einen 2D in einen 1D Array abspeichert und ich werde dann zum dritten mal sagen dass es NICHT geht.


----------



## nrg (6. Dez 2010)

Du machst das schon richtig. Erst einlesen, dann verarbeiten. Auch dein Gedanke das zeilenweise zu verabeiten ist nicht verkehrt. ich frage mich, was du dann mit deinem 2D Array willst.
Hier mal ein kleines Beispiel. Das einzige was ich hier mehr mache als du ist ein wenig oo und die Methode getNextEntity.


```
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class CSVFile {

	private int iterator;
	private File file;
	private List<String> list;
	private String delim;

	public CSVFile(File file, String delim) {
		this.file = file;
		this.list = new ArrayList<String>();
		this.delim = delim;
		this.iterator = 0;
	}

	public void setDelimiter(String delim) {
		this.delim = delim;
	}

	public void readFile() throws IOException {
		this.iterator = 0;
		BufferedReader buff = new BufferedReader(new FileReader(file));
		String line;
		while ((line = buff.readLine()) != null)	 
			list.add(line);
		buff.close();
	}

	public String[] getNextEntity() {
		return iterator >= list.size() ? null : list.get(iterator++).split(delim);
	}

	// Nur zum Tester hier in der Klasse
	public static void main(String[] args) throws IOException {
		CSVFile csv = new CSVFile(new File("C:/test.csv"), ";");
		csv.readFile();
		String[] entity = null;
		while ((entity = csv.getNextEntity()) != null) {
			// Dein Verarbeitungsprozess mit dem 1D Array entity
		}
	}
}
```

du kannst das natürlich auch wie bei einem StringTokenizer mit hasMoreEntitys() abbilden. Das bleibt dir überlassen. Bei meinem Beispiel sollte man halt auf jedenfall mitdokumentieren, dass getNextEntity auch null liefern kann.

edit: weitere getter/setter bzw. Konstruktoren überlasse ich mal dir


----------



## fastjack (6. Dez 2010)

Wieso soll man aus einem 2D-Array kein 1D-Array machen können? Ist vielleicht hierfür nicht geeignet, es geht aber trotzdem, wenn die Anzahl an Feldern einer "Zeile" gleich sind.
Ein 2D-Array als 1D-Array sieht so aus, das alle Datenfelder hintereinander liegen, in einer großen Liste sozusagen. Du musst nur wissen, wieviele Felder einer Zeile entsprechen, mehr nicht.

Es gibt natürlich CSV-Dateien, wo Spalten am Ende fehlen. Es gibt auch mehrzeilige Spalten, und und und. Deshalb würde ich immer Flatpack raten.


----------



## Andi_CH (6. Dez 2010)

fastjack hat gesagt.:


> Wieso soll man aus einem 2D-Array kein 1D-Array machen können? Ist vielleicht hierfür nicht geeignet, es geht aber trotzdem, wenn die Anzahl an Feldern einer "Zeile" gleich sind.



Ok, ich mach aus deinem Auto auch ein flaches Blech - das geht auch, aber ich glaube nicht, dass es in deinem Sinn ist ;-)

Grundsätzlich kann ich ALLES in einen Bytestream packen, sonst würde ja das Internet nicht funktionieren, aber dann muss die Frage etwas präziser gestellt werden.


----------



## DBR89 (6. Dez 2010)

nrg hat gesagt.:


> Du machst das schon richtig. Erst einlesen, dann verarbeiten. Auch dein Gedanke das zeilenweise zu verabeiten ist nicht verkehrt. ich frage mich, was du dann mit deinem 2D Array willst.
> Hier mal ein kleines Beispiel. Das einzige was ich hier mehr mache als du ist ein wenig oo und die Methode getNextEntity.
> 
> 
> ...



Ok wie kann ich das jetzt mit der Ausgabe als XML zusammenführen? folgenden Code verwende ich dafür:
[Java]
/*
 * ToXML.java
 */

import java.util.logging.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

public class ToXML {

    private StreamResult out;
    private TransformerHandler th;
    private AttributesImpl atts;
    String[] list = {
    "1;BTSSM;Berlin/GueterBhf-Schoenholz 315;Cell-ID: 43000043;52,571111;13,383056;882;1524",
    "1;BTSSM;Lünen 0;Cell-ID: 43000188;51,608333;7,524444;872;678"};



    public ToXML() {
        try {
            out = new StreamResult("data.xml");
            initXML();
            for (String str : list) {
                process(str);
            }
            closeXML();
        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(ToXML.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(ToXML.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void initXML() throws TransformerConfigurationException, SAXException {
        SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        th = tf.newTransformerHandler();
        Transformer serializer = th.getTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
        // pretty XML output:
        serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        th.setResult(out);
        th.startDocument();
        atts = new AttributesImpl();
        th.startElement("", "", "gpx", atts);
    }

    private void process(final String s) throws SAXException {
        String[] elements = s.split(";");
        atts.clear();
        atts.addAttribute("", "", "lat", "", "" + elements[4]);
        atts.addAttribute("", "", "lon", "", "" + elements[5]);
        th.startElement("", "", "wpt", atts);
        atts.clear();
        th.startElement("", "", "name", atts);
        th.characters(elements[3].toCharArray(), 0, elements[3].length());
        th.endElement("", "", "name");
        th.startElement("", "", "cmt", atts);
        th.characters(elements[1].toCharArray(), 0, elements[1].length());
        th.endElement("", "", "cmt");
        th.startElement("", "", "desc", atts);
        String desc = elements[2] + " Releasecause: " + elements[6] + " Sum: " + elements[7];
        th.characters(desc.toCharArray(), 0, desc.length());
        th.endElement("", "", "desc");
        th.endElement("", "", "wpt");
    }

    private void closeXML() throws SAXException {
        th.endElement("", "", "gpx");
        th.endDocument();
    }

    public static void main(final String args[]) {
        ToXML toXML = new ToXML();
    }
}
[/Java]


----------



## nrg (6. Dez 2010)

das ist doch 1 zu 1 der Code von André Uhres...


----------



## DBR89 (6. Dez 2010)

nrg hat gesagt.:


> das ist doch 1 zu 1 der Code von André Uhres...



allerdings würde ich gerne ein Array verwenden und mein code funktioniert leider nicht


----------



## nrg (6. Dez 2010)

du musst doch einfach verstehen, was du machst.

Wenn du der Aufgabe nicht gewachsen bist, gönn dir Fachliteratur dazu. Benutz XML Parser (dom4j, jdom).

Wenn du damit überhaupt nicht klar kommst, lass es sein oder nehm was fertiges (> FlatPack).


----------



## DBR89 (7. Dez 2010)

Hallo Leute, ich habe meine Problematik gelöst. Das ganze wird jetzt nun nicht mehr in einem Array gespeichert, sondern in einer Liste, die ich dann an das toXML übergebe.

Danke trotzdem für die Unterstützung.

NRG, sei mir nicht Böse, aber nicht so abgehoben. Habe mit Java erst angefangen und habe die geposteten Programme ausprobiert. Aber auch dir Danke.

Gruß Dennis

PS: Hier das Resultat

```
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;


public class translator {
	
	public List<String> translator() {
        
        // Einlesen des Files und spliten
        FileReader myFile = null;
        BufferedReader buff = null;
        final List<String> lines = new ArrayList<String>();
     
        try {
            myFile = new FileReader("Test_Koordinaten_BTSSM.csv");
            buff = new BufferedReader(myFile);
            String line;
            while ((line = buff.readLine()) != null) {
               // System.out.println(line); // kontrolle was eingelesen
     
                lines.add(line);
            }
        } catch (IOException e) {
            System.err.println("Error2 :" + e);
        } finally {
            try {
                buff.close();
                myFile.close();
            } catch (IOException e) {
                System.err.println("Error2 :" + e);
            }
        }
     
        final String[][] valuesArray = new String[lines.size()][];
        int cnt = 0;
        for (final String line : lines) {
            valuesArray[cnt++] = line.split(",");
        }
        return lines;
	}
        
	//Umwandeln der Liste in GPX(XML) Code
        private StreamResult out;
        private TransformerHandler th;
        private AttributesImpl atts;
        List<String> list = translator();

        
     
        public translator() {
            try {
                out = new StreamResult("data.xml");
                initXML();
                for (String str : list) {
                    process(str);
                }
                closeXML();
            } catch (TransformerConfigurationException ex) {
                Logger.getLogger(translator.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SAXException ex) {
                Logger.getLogger(translator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
     
        private void initXML() throws TransformerConfigurationException, SAXException {
            SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
            th = tf.newTransformerHandler();
            Transformer serializer = th.getTransformer();
            serializer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
            // pretty XML output:
            serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            th.setResult(out);
            th.startDocument();
            atts = new AttributesImpl();
            th.startElement("", "", "gpx", atts);
        }
     
        private void process(final String s) throws SAXException {
            String[] elements = s.split(";");
            atts.clear();
            atts.addAttribute("", "", "lat", "", "" + elements[4]);
            atts.addAttribute("", "", "lon", "", "" + elements[5]);
            th.startElement("", "", "wpt", atts);
            atts.clear();
            th.startElement("", "", "name", atts);
            th.characters(elements[3].toCharArray(), 0, elements[3].length());
            th.endElement("", "", "name");
            th.startElement("", "", "cmt", atts);
            th.characters(elements[1].toCharArray(), 0, elements[1].length());
            th.endElement("", "", "cmt");
            th.startElement("", "", "desc", atts);
            String desc = elements[2] + " Releasecause: " + elements[6] + " Sum: " + elements[7];
            th.characters(desc.toCharArray(), 0, desc.length());
            th.endElement("", "", "desc");
            th.endElement("", "", "wpt");
        }
     
        private void closeXML() throws SAXException {
            th.endElement("", "", "gpx");
            th.endDocument();
        }
	    
    
    public static void main(final String args[]) {
        translator	toXML = new translator();
    }

}
```


----------



## André Uhres (7. Dez 2010)

DBR89 hat gesagt.:


> Das ganze wird jetzt nun nicht mehr in einem Array gespeichert, sondern in einer Liste, die ich dann an das toXML übergebe.



Hallo Dennis,

eigentlich könnten wir uns ja auch dem Umweg über eine Liste sparen. Etwa so:


```
...

public final class Translator {

    //Umwandeln der Liste in GPX(XML) Code
    private StreamResult out;
    private TransformerHandler th;
    private AttributesImpl atts;

    public Translator() {
        try {
            out = new StreamResult("data.xml");
            initXML();
            // Einlesen des Files und spliten
            BufferedReader buff = null;
            try {
                buff = new BufferedReader(new FileReader("Test_Koordinaten_BTSSM.csv"));
                String line;
                while ((line = buff.readLine()) != null) {
                    process(line);
                }
            } catch (IOException e) {
                System.err.println(e);
            } catch (SAXException ex) {
                System.err.println(ex);
            } finally {
                try {
                    buff.close();
                } catch (IOException e) {
                    System.err.println(e);
                }
            }
            closeXML();
        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(Translator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(Translator.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void initXML() throws TransformerConfigurationException, SAXException {
...
    }

    private void process(final String s) throws SAXException {
...
    }

    private void closeXML() throws SAXException {
        th.endElement("", "", "gpx");
        th.endDocument();
    }

    public static void main(final String args[]) {
        Translator toXML = new Translator();
    }
}
```

Gruß,
André


----------

