XML to CSV in C - Brauche Hilfe bei einer Praktikumsaufgabe



  • Hallo, dies ist mein erste Beitrag hier.
    Im Zuge eines Praktikums muss ich aus einer XML bestimmte Daten auslesen und diese in eine CSV-Datei schreiben. Ich versuche seit Tagen dieses Problem zu lösen, aber ich bekomme es einfach nicht hin.

    Vorgegebene XML:
    <Aktienliste>
    <Boerse>XETRA</Boerse>
    <Datum>17.02.2012</Datum>
    <Aktie>
    <WKN>A1EWWW</WKN>
    <Name>adidas</Name>
    <Kurs>57.98</Kurs>
    <AG>adidas</AG>
    </Aktie>
    <Aktie>
    <WKN>840400</WKN>
    <Name>Allianz N</Name>
    <Kurs>90.46</Kurs>
    <AG>Allianz</AG>
    </Aktie>
    </Aktienliste>

    Die CSV soll nachher so aussehen:

    WKN, Name, Kurs, AG, Datum, Boerse
    A1EWWW, adidas, 57.98, adidas, 17.02.2012, XETRA
    840400, Allianz N, 90.46, Allianz, 17.02.2012, XETRA

    Mein Code sieht bis jetzt so aus:

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    
    #include "xml2csv.h"
    
    /*Globale Variablen*/
    int const LINE_LENGTH = 80;
    int const MAX_CHAR = 20;
    FILE *inputFile, *outputFile;
    
    void PrintFile(FILE *output){
        char puffer[81];
        while(!feof(output)){
            if(fgets(puffer, LINE_LENGTH, output) != NULL){
                printf("%s", puffer);
            }
        }
    }
    
    void FileNotFoundException(int errorcode){
        switch(errorcode){
            case EDOM:
            perror("FileNotFoundException");
            exit(1);
            break;
            default:
                printf("Exception");
        }
    }
    
    void WriteCsvHeader(FILE *csvFile){
        char csvHeader[] = "WKN, Name, Kurs, AG, Datum, Boerse";
        fprintf(csvFile, "%s", csvHeader);
    }
    
    int main(int argc, char* argv[]){
        printf("\n\n***************************XML to CSV***************************\n\n");
    
        /*Ueberpruefen ob 3 Argumente in der Kommandozeile eingegeben wurden*/
        if( argc < 3 ){
            printf("Verwendung : %s [inputFile.xml] [outputFile.csv]\n", *argv);
            return 0;
        }
    
        /*Oeffnen der Files*/
        inputFile = fopen(argv[1], "rb");
        outputFile = fopen(argv[2],"wb");
    
        /*Ueberpruefung ob inputFile vorhanden*/
        if( inputFile == NULL ){FileNotFoundException(EDOM);}
        else{printf("Datei erfolgreich geoeffnet!\n\n");}
    
        /*Ausgabe inputFil*/
        printf("Ausgabe : %s \n\n", argv[1]);
        PrintFile(inputFile);
    
        WriteCsvHeader(outputFile);
        /*Schliessen der Files*/
        fclose(inputFile);
        fclose(outputFile);
    
        /*Ausgabe outputFile*/
        outputFile = fopen(argv[2],"r");
        printf("\n\nAusgabe: %s \n\n", argv[2]);
        PrintFile(outputFile);
    
        /*Schliessen outputFile*/
        fclose(outputFile);
        return 0;
    }
    

    Ich habe schon alles mögliche mit gets, fgets, getc, Funktionen der cstring (strstr, strtok), hab bei Galileo Openbooks in dem Buch C von A bis Z von Jürgen Wolf geschaut...

    Ich weiß einfach nicht wie ich es umsetzte, dass wenn ein ">" kommt das Programm solange die Zeichen speichert bis ein "<" kommt.

    Hoffe ich habe meine Problem soweit verständlich erklärt und mir kann da jemand bei helfen 🙂

    Dazu sei vielleicht noch zu sagen, dass ich mich erst seit 3 Wochen mit C beschäftige.


  • Mod

    TomIstVerzweifelt schrieb:

    Ich habe schon alles mögliche mit gets, fgets, getc, Funktionen der cstring (strstr, strtok), hab bei Galileo Openbooks in dem Buch C von A bis Z von Jürgen Wolf geschaut...

    Das sind die beiden denkbar schlechtesten Quellen, was das Programmieren angeht. Nutze sie nicht, versuch zu vergessen, was du gelernt hast (wenn man da überhaupt von lernen sprechen kann).

    Ich weiß einfach nicht wie ich es umsetzte, dass wenn ein ">" kommt das Programm solange die Zeichen speichert bis ein "<" kommt.

    Wo ist das Problem? Du weißt, wie du Zeichen einliest. Jetzt noch ein paar Kontrollstrukturen (Schleifen, if-Abfragen) und du hast alles was du brauchst. Mit (f)scanf kannst du dir auch einen abgedrehten Formatstring ausdenken, der gleich ein ganzes XML-Tag zerlegt.



  • Für einen Anfänger, der du ja wohl bist, schon mal ziemlich anspruchsvoll.
    Hier eine Variante mit abgedrehtem Formatstring, aufwändiger als normal wegen der beiden durchgereichten Tags Boerse+Datum.
    Diverse Fehlerbehandlung kannst du natürlich selbst machen.

    typedef char String[99];
    
    struct Liste{
    String s[1000][6];
    int z;} liste;
    
    int indexOf(char *s)
    {
    	return !strcmp(s,"Boerse")?5:!strcmp(s,"Datum")?4:!strcmp(s,"AG")?3:!strcmp(s,"Kurs")?2:strcmp(s,"WKN")!=0;
    }
    
    void aktion(struct Liste *liste,char *k,char *v)
    {
    	String t="";
    	if( sscanf(v,"%s",t),*t )
    		strcpy(liste->s[liste->z][indexOf(k)],v);
    	else
    	{
    		int i=0;
    		liste->z++;
    		for(;i<6;++i)
    			strcpy(liste->s[liste->z][i],liste->s[liste->z-1][i]);
    	}
    }
    
    void lies(struct Liste *liste,char *fname)
    {
    	FILE *f=fopen(fname,"r");
    	String k,v;
    	while( 2==fscanf(f,"%[^<]<%[^>]>",v,k) )
    		if( *k=='/' )
    			aktion(liste,k+1,v);
    	fclose(f);
    	--liste->z;
    }
    
    int main()
    {
    	lies(&liste,"x.txt");
    	while( liste.z-- )
    		printf("%s;%s;%s;%s;%s;%s\n",liste.s[liste.z][0],liste.s[liste.z][1],liste.s[liste.z][2],liste.s[liste.z][3],liste.s[liste.z][4],liste.s[liste.z][5]);
    	return 0;
    }
    


  • Hast du die lösung inzwischen finden können?


Anmelden zum Antworten