Tag aus XML Datei auslesen
-
Ich versuche gerade eine Funktion in einer Klasse zu schreiben, die eine XML Datei ausließt und die "Losung" für ein bestimmtes Datum zurück gibt. Komme irgendwie gerade nicht weiter.
Hier nun meine Frage:
Wie kann ich mir den entsprechenden Tag holen und die Datei nach einem bestimmten Datum durchsuchen?
Sorry falls ich undeutlich bin. abreite noch nicht lange und nicht sehr viel mit c++.
Das ist alles was ich bisher von der Funktion habe:
bool Losung_XML::ladenLosung(string Dateiname) { ifstream los; los.open("Losungen.xml",ios::in); while(!los.eof()) { string a; los>>a; getline(los,a); } }Danke für eure Hilfe
-
bool XMLladen(string dateiname) { ifstream in(dateiname.c_str()); if(!in) return false; while(in.good()){ string str; getline(in, str); //tue etwas mit str cout << str << endl; } return true; }
-
na da lag ich dann ja fast richtig.
Aber wie lese ich ein bestimmtes Datum ein?Sorry hätte vielleicht noch die datei mit posten sollen...
<?xml version="1.0" encoding="UTF-8" ?> - <dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2011-01-01T00:00:00"> - <Losungen> <Datum>2011-01-01T00:00:00</Datum> <Wtag>Samstag</Wtag> <Sonntag>Neujahr</Sonntag> <Losungstext>Besser ein Gericht Kraut mit Liebe als ein gemästeter Ochse mit Hass.</Losungstext> <Losungsvers>Sprüche 15,17</Losungsvers> <Lehrtext>Lasst uns wahrhaftig sein in der Liebe und wachsen in allen Stücken zu dem hin, der das Haupt ist, Christus.</Lehrtext> <Lehrtextvers>Epheser 4,15</Lehrtextvers> </Losungen> - <Losungen> <Datum>2011-01-02T00:00:00</Datum> <Wtag>Sonntag</Wtag> <Sonntag>2. Sonntag nach Weihnachten</Sonntag> <Losungstext>Alle Völker werden sich verwundern und entsetzen über all das Gute und über all das Heil, das ich Jerusalem geben will.</Losungstext> <Losungsvers>Jeremia 33,9</Losungsvers> <Lehrtext>Da wir nun gerecht geworden sind durch den Glauben, haben wir Frieden mit Gott durch unsern Herrn Jesus Christus.</Lehrtext> <Lehrtextvers>Römer 5,1</Lehrtextvers> </Losungen> - <Losungen> <Datum>2011-01-03T00:00:00</Datum> <Wtag>Montag</Wtag> <Sonntag /> <Losungstext>Ich habe mein Angesicht im Augenblick des Zorns ein wenig vor dir verborgen, aber mit ewiger Gnade will ich mich deiner erbarmen, spricht der HERR, dein Erlöser.</Losungstext> <Losungsvers>Jesaja 54,8</Losungsvers> <Lehrtext>Alle haben gesündigt und die Herrlichkeit Gottes verspielt. Gerecht gemacht werden sie ohne Verdienst aus seiner Gnade durch die Erlösung, die in Christus Jesus ist.</Lehrtext> <Lehrtextvers>Römer 3,23-24</Lehrtextvers> </Losungen>Der Sinn soll sein, dass ich später ein Datum eingeben kann und ich dann die dazu gehörige Losung bekomme.
-
Dazu müsstest du jetzt den Inhalt der XML-Datei auseinandernehmen. Entweder du schreibst es von Hand oder du suchst mal im Netz nach einer brauchbaren XML-Bibliothek, die dir die Aufgabe abnimmt.
-
ginge das nicht irgendwie indem ich den Tag Datum einlese und in einer Schleife das ganze solange durchlaufe bis das gewünschte Datum gefunden wurde?
Folgendes soll/ist gemacht werden (Falls ich das ganze ungenau beschrieben habe):
Habe mir als erstes eine Struktur erstellt, die die Bestandteile von der XML Datei aufnehmen kann.
Danach habe ich mir eine Klasse erstellt die folgendes können soll:
- Die XML Datei auslesen und die Losung für ein bestimmtes Datum an das
Hauptprogramm (Unit1.cpp) zurückgibt.Hier mal das was ich bisher erstellt habe mehr oder eher weniger richtig:
Unit1.cpp (Hauptprogramm)
#include<iostream> #include<fstream> using namespace std; #include"Unit2.h" int main(int argc, char* argv[]) { Losung x; //struct Losung_XML y; //class cout<<"Datum"<<x.Datum<<endl; cout<<"Losungstext"<<x.Losungstext<<endl; cout<<"Losungsvers"<<x.Losungsvers<<endl; cout<<"Lehrtextvers"<<x.Lehrtextvers<<endl; getchar(); return 0; }Unit2.cpp:
#include<iostream> #include<fstream> #include<string> using namespace std; #include "Unit2.h" Losung Losung_XML::zeigenSpruch(char Datum) { return feld[Datum]; } bool Losung_XML::ladenLosung(string dateiname) { ifstream in(dateiname.c_str()); //Ist das so korrekt bekomme eine //Fehlermeldung: Erwartet. //Kann leider nix mit "Erwartet" anfangen if(!in) return false; while(in.good()) { string str; getline(in, str); //tue etwas mit str cout << str << endl; } return true; }Unit2.h:
#include<iostream> #include<string> using namespace std; struct Losung { char Datum, Wtag, Sonntag, Losungstext, Losungsvers, Lehrtext, Lehrtextvers; }; class Losung_XML { private: Losung feld[366]; int AnzahlLosungen; public: Losung zeigenSpruch(char Datum); bool ladenLosung(string dateiname); Losung1(); };
-
Wie gesagt, das mußt du entweder selber schreiben oder suchen (im Standard C++ gibt es afaik keine XML-Verarbeitung). Für dich würde es eventuell schon reichen, der Loesung-Klasse eine Einlese-Funktion zu geben, die aus der Datei einen <Losungen>...</Losungen> Block einliest und die einzelnen Unter-Elemente korrekt in die Member verteilt.
(PS: char ist wohl etwas zu klein für die Datei-Inhalte
Nimm da lieber std::string)
-
Also deutlich einfacher ist so etwas mit einer gescheiten XML-Bibliothek. Ich bevorzuge dabei RapidXml, weil es einfach schön schnell, Header-only (also leicht einzubinden), leicht zu verwenden und frei benutzbar ist.
-
Sorry für die dumme frage aber muss ich std::string als bibliothek includieren? oder kann ich da einfach string davor schereiben?
Das mit dem Blockweise einlesen is ne Klasse Idee. Wenn man wüsste wie.
In einer Schleife? bis </Losungen> erreich wurde ?
-
für die String-Klasse brauchst du nur den richtigen Header - und der heißt <string> und ist Teil der C++-Standardbibliothek.
(Edit: Wenn ich mir deine letzten Beispiele ansehe - den hast du sogar schon verwendet)Irgendwer schrieb:
Also deutlich einfacher ist so etwas mit einer gescheiten XML-Bibliothek.
Dem kann ich nur zustimmen. Das von Hand zu machen, dürfte in reichlich Bastelarbeit enden.
-
eingebunden habe ich diese jetzt erfolgreich.
aber mir ist immernoch nicht klar wie jetzt damit arbeiten kann.
Wie kann ich jetzt damit nach dem Datum suchen kann.
-
Ein bisschen solltest du dich schon selbst informieren:
http://rapidxml.sourceforge.net/manual.htmlZitat:
Entire parser is contained in a single header file, so no building or linking is neccesary. To use it you just need to copy rapidxml.hpp file to a convenient place (such as your project directory), and include it where needed. You may also want to use printing functions contained in header rapidxml_print.hpp.
-
Ich würde ja mehr selber suchen aber (Möchte mich wirklich nicht ausreden!) ich habe noch so meine schwierigkeiten bei der Umsetzung. Ich kann mir meistens schon denken wie es geht nur umsetzen in c++ Anweisungen kann ich nie wirklich.
versteh im Moment wirklich überhaupt nicht wie ich die XML Datei einlesen und nach dem Datum suchen kann.
-
Erstmal muss du dir ein Objekt der Klasse rapdidxml::xml_document erstellen, welches dann mit Hilfe der Methode parse() einen DOM-Tree erstellt.
Relativ praktisch sind auch die Iteratoren (nicht dokumentiert, aber der Quellcode ist sehr einfach zu verstehen) oder auch rapidxml::file.Nach dem ersten Datums-Node könntest du dann folgendermaßen suchen:
namespace rx = rapidxml; rx::file<> file("Dateipfad hier"); rx::xml_document<> doc; doc.parse<0>(file.data()); rx::xml_node<>* node = doc.first_node("dataroot")->first_node("Losungen")->first_node("Datum"); const char* datum = node.value();Könnte sein, dass ein Fehler drin ist, aber da musst du selbst ein bisschen herumprobieren. Wenn alles richtig ist, hättest du das Datum jetzt als
const char*.
-
brauche ich das hier dann nicht mehr?
bool Losung_XML::ladenLosung(string dateiname) { ifstream in(dateiname.c_str()); if(!in) return false; while(in.good()) { string str; getline(in, str); //tue etwas mit str cout << str << endl; } return true; }
-
Ja, du brauchst es nicht mehr.
Aber bevor du einfach so meinen Code übernimmst, solltest du versuchen zu verstehen, was da vor sich geht. Ansonsten bringt das alles nichts...
-
Wenn man jetzt noch verstehen würde was hier
rapdidxml::xml_document erstellen, welches dann mit
Hilfe der Methode parse() einen DOM-Tree erstellt.mit gemeint ist...
So etwa?rapdidxml::xml_document
void parse(Ch *text); //Meinst du das mit Objekt der Klasse
//rapdidxml::xml_document?Bin schon interessiert das ganze zu verstehen.
Hast du icq oder so ??
hier meine Daten könntest du mich bitte anschreiben:
icq: 234-452-563
AIM: Pharao50
E-Mail: Pharao56694@t-online.dewäre echt klasse von dir.
-
pharao50 schrieb:
mit gemeint ist...
So etwa?rapdidxml::xml_document
void parse(Ch *text); //Meinst du das mit Objekt der Klasse
//rapdidxml::xml_document?Nein. Hast du schon gelernt, wie man Objekte anlegt und wie man deren Methoden aufruft?
ohne Gewähr (ich hab mir die Doku nicht durchgelesen, aber vermutlich mußt du noch irgendwo den Dateinamen übergeben):
rapidxml::xml_document xmlfile;//Objekt anlegen xmlfile.parse(dateiinhalt);//und auf den Inhalt deiner XML-Datei loslassen
-
Nein Objekte verwenden hatten wir glaub ich noch nicht.
Wenn ich das so:
rapidxml::xml_document xmlfile;//Objekt anlegen xmlfile.parse(dateiinhalt);mache bekomme ich diese Meldung:
Template 'rapidxml::xml_document<Ch>' kann ohne Spezifizierungsparameter nicht verwendet werden.
-
pharao50 schrieb:
Nein Objekte verwenden hatten wir glaub ich noch nicht.
Dann hast du sie bisher nur unbewußt verwendet - siehe bei deinen Streams

Wenn ich das so:
rapidxml::xml_document xmlfile;//Objekt anlegen xmlfile.parse(dateiinhalt);mache bekomme ich diese Meldung:
Template 'rapidxml::xml_document<Ch>' kann ohne Spezifizierungsparameter nicht verwendet werden.
Da habe ich wohl nicht genau hingesehen - xml_document ist ja ein Template, da mußt du "rapidxml::xml_document<char> xmlfile;" schreiben.
-
jetzt kommt in dieser Zeile:
xmlfile.parse(dateiinhalt);Bezeichner xmlfile merhfach deklariert.
Was ist hier falsch?