[Hilfe] .csv zu .xml



  • Heyho,

    dass hier ist mein erster Post daher weiß ich nicht ob ich den Post hier richtig anlege. Zu meinem Problem:
    Ich habe die Aufgabe bekommen ein Programm zu schreiben welches eine .csv Datei in eine .xml Datei umwandelt.
    Leider habe ich geringe Kenntnisse in c++ und benötige daher eure Hilfe.

    Meine .csv Datei sieht so aus:
    Name, Typ
    vgaName, ApexClass
    vg.Customer, ApexPage
    vgaCustomer, ApexClass
    Contract, CustomObject
    -------------------------------------------
    XML Datei sollte folgendermaßen aussehen:

    <Type>
    <ApexClass>
    <value>vgaName</value>
    <value>vgaCustomer</value>
    </ApexClass>
    <CustomObject>
    <value>Contract</value>
    </CustomObject>
    <ApexPage>
    <value>vg.Customer</value>
    </ApexPage>
    </Type>

    Hat jemand eine Idee und kann mir helfen?
    Vielen Dank im vorraus
    Mit freundlichen Grüßen


  • Mod

    Woran scheitert es denn? Einlesen? Verarbeitung? Ausgabe? Was hast du dir denn schon überlegt? Es wird dir sicher niemand die Aufgabe komplett lösen. Wenn du so eine Aufgabe erhalten hast, kannst du nicht komplett ahnungslos sein.



  • Das ist mir bewusst das keiner die Aufgabe ganz lösen wird 🙂
    Ich durfte mir die Programmiersprache aussuchen und habe mich letzendlich für c++ entschieden. Ich weiß leider nicht wie ich genau vorgehen soll, mein erster Gedanke war es die Werte in eine Liste einzulesen um erstmal zu gucken wie viele Blöcke ich erstellen muss. (<Apexclass>,<CustomObject, etc). Leider weis ich nicht wie ich herrausfinde wie viele Blöcke ich jetzte genau habe.


  • Mod

    Da bietet sich doch eine assoziative Datenstruktur an, damit das ganz von alleine geschieht.



  • Könntest du mir das etwas genauer erklären?
    Danke!



  • SepP97 schrieb:

    Das ist mir bewusst das keiner die Aufgabe ganz lösen wird 🙂

    Warum nicht?

    #include <iostream>
    #include <fstream>
    #include <map>
    #include <vector>
    #include <string>
    
    int main()
    {
        using namespace std;
        map< string, vector< string > > data;
        ifstream input("eingabe.csv");
        if( !input.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        input.ignore( 999, '\n' );  // erste Zeile überlesen
        for( string value, type; getline( getline( input >> ws, value, ',' ) >> ws, type, '\n' ); )
            data[type].push_back( value );
        if( !input.eof() )
            cerr << "Fehler beim Lesen der Datei" << endl;
    
        ofstream output("ausgabe.xml");
        output << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl;    // encoding="ISO-8859-1" für Westeuropäische Sprachen
        output << "<Type>\n";
        for( auto& values: data )
        {
            output << "<" << values.first << ">\n";
            for( auto& value: values.second )
                output << "  <value>" << value << "</value>\n";
            output << "</" << values.first << ">\n";
        }
        output << "</Type>" << endl;
        return 0;
    }
    


  • Werner Salomon schrieb:

    SepP97 schrieb:

    Das ist mir bewusst das keiner die Aufgabe ganz lösen wird 🙂

    Warum nicht?

    #include <iostream>
    #include <fstream>
    #include <map>
    #include <vector>
    #include <string>
    
    int main()
    {
        using namespace std;
        map< string, vector< string > > data;
        ifstream input("eingabe.csv");
        if( !input.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        input.ignore( 999, '\n' );  // erste Zeile überlesen
        for( string value, type; getline( getline( input >> ws, value, ',' ) >> ws, type, '\n' ); )
            data[type].push_back( value );
        if( !input.eof() )
            cerr << "Fehler beim Lesen der Datei" << endl;
    
        ofstream output("ausgabe.xml");
        output << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl;    // encoding="ISO-8859-1" für Westeuropäische Sprachen
        output << "<Type>\n";
        for( auto& values: data )
        {
            output << "<" << values.first << ">\n";
            for( auto& value: values.second )
                output << "  <value>" << value << "</value>\n";
            output << "</" << values.first << ">\n";
        }
        output << "</Type>" << endl;
        return 0;
    }
    

    Werde ich gleich mal testen und mich sofort melden, sieht schonmal sehr gut aus.
    Vielen Dank!



  • Folgende Fehlermeldung:
    In function int main()': 26 expected primary-expression before "auto" 26 expected;' before "auto"
    34 expected primary-expression before "return"
    34 before "return"



  • Dein Compiler ist wohl etwas veraltet.



  • Was schlägst du mir für einen Compiler vor?



  • SepP97 schrieb:

    Folgende Fehlermeldung:
    [i] In function `int main()':
    26 expected primary-expression before "auto" ...

    ersetze die for-Schleife (Zeile 26-32) durch folgenden Code:

    // für Compiler mit C++03
        for( map< string, vector< string > >::iterator values = data.begin(); values != data.end(); ++values )
        {
            output << "<" << values->first << ">\n";
            for( vector< string >::iterator value = values->second.begin(); value != values->second.end(); ++value )
                output << "  <value>" << *value << "</value>\n";
            output << "</" << values->first << ">\n";
        }
    


  • Programm läuft ohne Problem. Danke für die schnelle Hilfe!
    Die ausgabe.xml sieht aber folgender maßen aus:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <Type>
    </Type>

    Meine eingabe.csv:
    *
    Name;Type
    VCAppSettings__c;CustomObject
    CM_SALES_APP_SETTINGS__c;CustomObject
    CM_SALES_PROFILE_SETTINGS__c;CustomObject
    SCApplicationSettings__c;CustomObject
    triggersettings__c;CustomObject*



  • for( string value, type; getline( getline( input >> ws, value, ',' ) >> ws, type, '\n' ); )
            data[type].push_back( value );
    

    Kann das evlt. mal jmd. erklären ????



  • SepP97 schrieb:

    Programm läuft ohne Problem. Danke für die schnelle Hilfe!
    Die ausgabe.xml sieht aber folgender maßen aus:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <Type>
    </Type>

    Meine eingabe.csv:
    *
    Name;Type
    VCAppSettings__c;CustomObject
    CM_SALES_APP_SETTINGS__c;CustomObject
    CM_SALES_PROFILE_SETTINGS__c;CustomObject
    SCApplicationSettings__c;CustomObject
    triggersettings__c;CustomObject*

    vorher sah sie noch anders aus:

    SepP97 schrieb:

    Meine .csv Datei sieht so aus:
    Name, Typ
    vgaName, ApexClass
    vg.Customer, ApexPage
    vgaCustomer, ApexClass
    Contract, CustomObject

    siehe Zeile 18; tausche , gegen ;



  • Wie konnte ich das nur übersehen o.O
    Vielen Dank an alle!



  • Hat das jetzt dem guten SepP97 geholfen etwas zu lernen?
    Hat er jetzt ggf. nur gelernt das richtige Forum um seine Hausarbeit zu bitten?
    Haben evtl. lernende Mitleser gelernt, dass man nichts selbst machen braucht, es findet sich immer ein "Werner Salomon"?
    @ Werner Salomon : nichts für ungut, Deine Motive mögen positiv sein.



  • Hallo Helmut,

    ich schließe aus Deinem Beitrag, dass es Du es gut findest, wenn hier jemand etwas lernt.
    what_tf hat eine Frage gestellt:

    what_tf schrieb:

    for( string value, type; getline( getline( input >> ws, value, ',' ) >> ws, type, '\n' ); )
            data[type].push_back( value );
    

    Kann das evlt. mal jmd. erklären ????

    Hier will offensichtlich jemand etwas lernen. Ich würde mir wünschen, dass er dabei von jemanden unterstützt wird. Wie wär's? Freiwillige vor! Wer geht mit gutem Beispiel voran?

    Gruß
    Werner



  • Ich versuchs selber, ganz grob mal..

    for( string value, type; getline( getline( input >> ws, value, ',' ) >> ws, type, '\n' ); )
    data[type].push_back( value );

    value und type verwirrte erst etwas aber sind "Laufvariablen" des Typs string mit komma getrennt...

    Hmmm das getline Kontsrukt ... (input skipt whitespace (?) liest in value... was macht das ',' ... liest evtl. bis zum komma ein ? ) das ganze gibt input stream zurück, liest in type ein bis zum '\n' und gibt wieder zurück und wird mit getline verwurschtelt... ach was weiß ich , da kriegst ja Kopfweh mann 🙂



  • Ja die for-Schleife ist etwas tricky. Also nochmal genau jetzt: Der erste string value, type Teil deklariert einfach nur zwei Variablen. Der ganze Rest ist die Abbruchbedingung der for-Schleife, denn nach dem zweiten Semikolon (da wo man normal die Laufvariable hochzählt) steht nur ein leerer Ausdruck. Also schauen wir uns die Abbruchbedingung mal genauer an:
    getline( getline( input >> ws, value, ',' ) >> ws, type, '\n' )

    Prinzipiell besteht der Teil aus zwei Funktionsaufrufen von getline. Die da beide wären:

    getline(..., value, ',' )
    getline(..., type, '\n' )
    

    Die Argumente für den Stream aus dem die Zeile ausgelesen werden soll habe ich der Übersicht halber mal durch ... dargestellt. Schaut man in die Dokumentation, sieht man das getline so viele Zeichen aus einem Stream ließt bis das Zeichen erreicht ist das man als dritten Parameter angibt. Außerdem gibt getline den Stream als Rückgabewert zurück, wir können also getline verschachteln. Jetzt fehlt eigentlich nur noch der >> ws Teil. Dadurch wird einfach Whitespace aus dem Stream eingelesen und ermöglicht Leerzeichen am Anfang der Zeile und nach dem Komma.

    Das Ganze läuft dann solange bis der Stream das Ende der Datei erreicht hat. Dank einem operator bool kann man Streams einfach auf Fehler testen.



  • Danke 👍 👍


Anmelden zum Antworten