FB18 - Das Forum für Informatik

fb18.de / Off-Topic / Hard- und Softwarefragen

XML-Datenstruktur in Programm einlesen

XML-Datenstruktur in Programm einlesen 2008-06-27 19:52
Anonymous Abuser
Hallo. Ich habe ein Programmierproblem (c++, aber da es um Konzepte geht ist das egal):
Ich will: Datenstruktur im XML_format in benutzerdef. Datenstruktur einlesen.

Dazu folgende Infos:

[1]XML-Struktur:
<Rezept 1> <Erdbeere> unt ut laoreet dolore magna a </Erdbeere> <Banane> m nonumy e </Banane> ... <Zitrone> usto duo dolores et ea rebum </Zitrone> </Rezept 1> <Rezept 2> ....
[1]Datenstruktur:
class Fruechte{ public: Fruechte(); ~Fruechte(void); void set_erdbeere(std::string text); void set_banane(std::string text); ... void set_zitrone(std::string text); //getter std::string get_banane(); std::string get_erdbeere(); ... std::string get_zitrone(); private: std::string _erdbeere; std::string _banane; ... std::string _zitrone; };
ich lese zur Zeit zeilenweise aus und Überprüfe auf <tag> und </tag>.
Die Suchstrings sind dabei fest im Code verankert.

Ich frage mich jetzt, ob es vielleicht möglich ist, die Lesefunktion kompakter zu machen…
Ein Problem sehe ich aber in der jeweils eigenständigen set-Methode für jede Membervariable…
Aber die Idee, die ich hatte, war eine Multimap zu verwenden, in der
[Suchstring, aufzurufende Memberfunktion] gespeichert sind… So wärs vielleicht möglich
die aufzurufende Memberfunktion dynamisch zu setzen…Meint ihr das ginge?

Oder habt ihr andre Realisierungsvorschläge?

RE: XML-Datenstruktur in Programm einlesen 2008-06-27 19:55
Anonymous Abuser
edit:
die entsprechende Funktion hätte ich jetzt hier auch gepostet..aber irgendwie geht das nich…ich arbeite dran…Scheinbar mag der Interpreter keinen C++ code in der form wie ich ihn posten will…

[1]die entsprechende Funktion zum lesen
int save_load::read-File(std::string path, std::vector<Fruechte> &Rezept) { std::string zeile, test; // Platzhalter für geladene Textzeile std::size_t posA1, posE1, posA2, posE2; // Vars zum Abtrennen der Daten std::string gefundener_suchtext; //aus Zeile extrahierte Daten Fruechte _frucht; int i = 0; // Zähler für die geladenen Datenzätze std::ifstream lesen("Y:\\Text.txt"); Rezept.clear(); //evtl. vorhandene Daten im Vector löschen while(getline(lesen,zeile))//zeilenweise einlesen { posA1 = posE1 = posA2 = posE2 = 0; posA1 = zeile.find("<"); //AnfangsTag START posE1 = zeile.find(">"); //AnfangsTag ENDE if (posA1!=std::string::npos && posE1!=std::string::npos && posA1 < posE1) { //Anfangsmarke gefunden!! gefundener_suchtext = zeile.substr(posA1+1,posE1-posA1-1); //alles hinter leerzeichen entfernen gefundener_suchtext = gefundener_suchtext.substr(0, gefundener_suchtext.find(" ")); // Endmarke herausfinden posA2 = zeile.rfind("</"); posE2 = zeile.rfind(">"); if (posA2 == 0) { posA2=-1; } test = zeile.substr(posA2+2,posE2-posA2-2); test = test.substr(0,test.find(" ")); if (0 == gefundener_suchtext.compare(test)) { if (gefundener_suchtext == "Rezept") { //Sollte der vorherige Datensatz fehlerhaft sein: if (i < 0) { i = 0; } //hier das laden des neuen veranlassen; } else if (gefundener_suchtext == "Erdbeere") { _frucht.set_Erdbeere(zeile.substr(posE1+1, posA2-posE1 -1)); } else if (gefundener_suchtext == "Banane") { _frucht.set_Banane(zeile.substr(posE1+1, posA2-posE1 -1)); } ... else if (gefundener_suchtext == "Zitrone") { _frucht.set_Zitrone(zeile.substr(posE1+1, posA2-posE1 -1)); } else if (gefundener_suchtext == "/Rezept") { if (i >= 0) { Rezept.push_back(_frucht); i++; i = 0; } } //else if case else { i= -1; } } else { i = -1; } } } // of while schleife return i; }

RE: XML-Datenstruktur in Programm einlesen 2008-06-27 19:56
Anonymer User
edit: problem solved… read file (zusammengeschrieben) mag er das board nich…

RE: XML-Datenstruktur in Programm einlesen 2008-06-27 22:31
Popcorn
Ich hätte jetzt einfach mal behauptet - auch wenn ich mit der Sprache nix am Hut habe - dass auch C++ eine Bibliothek zum Umgang mit XML hat.

RE: XML-Datenstruktur in Programm einlesen 2008-06-27 23:36
Fred
Ein Problem sehe ich aber in der jeweils eigenständigen set-Methode für jede Membervariable…
Aber die Idee, die ich hatte, war eine Multimap zu verwenden, in der
[Suchstring, aufzurufende Memberfunktion] gespeichert sind… So wärs vielleicht möglich
die aufzurufende Memberfunktion dynamisch zu setzen…Meint ihr das ginge?
In C++ geht so einiges [25]
// Abbildung von Strings auf Memberfunktionen von Fruechte std::map<std::string, void (Fruechte::*)(std::string)> setter; int main() {     setter["Erdbeere"] = &Fruechte::set_erdbeere;     setter["Banane"  ] = &Fruechte::set_banane;     setter["Zitrone" ] = &Fruechte::set_zitrone;     Fruechte fruechte;     std::string frucht = "Banane";     std::string eingelesen = "Hans Wurst";     (fruechte.*setter[frucht])(eingelesen); }
Oder habt ihr andre Realisierungsvorschläge?
Kannst Du nicht einfach in der Klasse eine Map von Strings auf Strings haben, und dann nur einen Setter? Eigentlich brauchst Du die Klasse Fruechte dann gar nicht mehr, dann tut's auch ne ganz normale Map.

RE: XML-Datenstruktur in Programm einlesen 2008-06-28 00:00
Anonymous Abuser
Kannst Du nicht einfach in der Klasse eine Map von Strings auf Strings haben, und dann nur einen Setter? Eigentlich brauchst Du die Klasse Fruechte dann gar nicht mehr, dann tut's auch ne ganz normale Map.
Hey, danke Fred. Das gefällt mir schon ganz gut [17].
Zu der Map: Entweder ich versteh dich nicht richtig, oder du mich nicht….bei der XML-Datei handelt es sich um ein Kostrukt das mehrere hundert <Rezepte> (oder whatever) beinhaltet.
Du würdest da jetzt nach deinem Vorschlag eine Map haben mit [Frucht_X, Anzahl] oder wie war das gemeint?

RE: XML-Datenstruktur in Programm einlesen 2008-06-28 00:12
Fred
Oh, ich habe gar nicht gesehen, dass da mehrere Rezepte sind. Der Inhalt sah so schwachsinnig aus, da dachte ich, dass das nur ein Beispiel mit sinnlosen Namen sei. Also meine Map wäre dann nur natürlich für ein Rezept.

Mir ist einfach der Zusammenhang zwischen "Erdbeere" und "unt ut laoreet dolore magna a" überhaupt nicht klar. Was hat das mit einem Rezept zu tun?

RE: XML-Datenstruktur in Programm einlesen 2008-06-28 00:22
Anonymous Abuser
Oh, ich habe gar nicht gesehen, dass da mehrere Rezepte sind. Der Inhalt sah so schwachsinnig aus, da dachte ich, dass das nur ein Beispiel mit sinnlosen Namen sei. Also meine Map wäre dann nur natürlich für ein Rezept.

Mir ist einfach der Zusammenhang zwischen "Erdbeere" und "unt ut laoreet dolore magna a" überhaupt nicht klar. Was hat das mit einem Rezept zu tun?

Hehe….Das ist nur ein schwachsinniges Beispiel gewesen und ist es immernoch [15] Das Hast du gut erkannt [7]. Nur vom Prinzip her erfüllt es die gleichen Anforderungen…Ich hätte auch eine Datenbankanwendung für Bücher oder dergleichen nehmen können…okay..dann wär das Beispiel vielleicht einleuchtender gewesen….

Nun..Erdbeeren waren halt bei den Römern schon beliebt ;) Siehe hier

RE: XML-Datenstruktur in Programm einlesen 2008-06-28 00:35
Fred
Besteht jedes Rezept aus den gleichen Arten von Früchten? Falls nicht, kann eine Banane mehrfach in einem Rezept vorkommen, mit verschiedenem Text?

RE: XML-Datenstruktur in Programm einlesen 2008-06-28 00:57
Anonymer User
Nein, Es gibt jede frucht nur 1x pro rezept und in jedem rezept ist der Text anders…
Zum Verständnis ein Beispiel zum Beispiel:
Rezept = Buch + Nr
Erdbeere = Buchtitel
Banane = Autor
Zitrone = Klappentext

Verstehste nu?

RE: XML-Datenstruktur in Programm einlesen 2008-06-28 01:35
Fred
Dann schlage ich folgendes Design vor:
- ein Buch ist ein unveränderliches Objekt ohne Setter, welches wir beim Erstellen bereits korrekt initialisieren
- es gibt eine (zunächst leere) Sammlung von Büchern, die wir sukzessive erweitern
- Wir befüllen eine leere map<string, string> in einer inneren Schleife mit eingelesenen Werten
- diese Werte benutzen wir zur Initialisierung des Buchs
class Buch { std::string titel; std::string autor; std::string klappentext; public: Buch(const std::string& titel, const std::string& autor, const std::string& klappentext) : titel(titel), autor(autor), klappentext(klappentext) {} const std::string& get_titel() const { return titel; } const std::string& get_autor() const { return autor; } const std::string& get_klappentext() const { return klappentext; } }; int main() { std::vector<Buch> buecher; while (noch_buecher_einzulesen) { std::map<std::string, std::string> info; while (noch_infos_einzulesen) { // Die naechsten beiden Zeilen Code // durch "Zeile aus XML Datei einlesen" ersetzen: std::string key = "Buchtitel"; std::string value = "The C++ Programming Language"; info[key] = value; } buecher.push_back(Buch(info["Buchtitel"], info["Autor"], info["Klappentext"])); } std::cout << buecher.size() << " Bücher eingelesen" << std::endl; } Natürlich solltest Du noch Fehlerbehandlung einbauen, falls nicht alle nötigen Infos für das Buch in der XML-Datei vorliegen.

RE: XML-Datenstruktur in Programm einlesen 2008-06-28 12:09
Anonymous Abuser
okay….das sieht auch nicht schlecht aus.
Ja Fehlerbehandlung hatte ich noch nicht implementiert. Zuerst muss ja die logische Struktur einigermaßen stehen [7].
Auf die Setter werde ich dennoch nicht ganz verzichten, sollte nachträglich doch noch einmal was an den Werten geändert werden müssen…

Danke sofar!