Tag aus XML Datei auslesen



  • 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.html

    Zitat:

    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.

    @Irgendwer:

    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.de

    wä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?



  • In dem kurzen Ausschnitt ist er auf jeden Fall nur einmal definiert. Hast du eventuell noch eine andere Variable mit dem selben Namen in deinem Programm?



  • Ich bin mir nicht so ganz sicher, ob du dich nicht für den Anfang übernimmst 😕
    Und rapidxml ist zwar schön aber nicht sooo leicht. Du musst z.B. die Datei selber in einen Buffer (z.B. std::vector<char>)einlesen, dafür sorgen, dass dieser Buffer genauso lange lebt wie das xml_document. Und auch das Manipulieren des DOM-Tree ist nicht so leicht (Stichwort memory_pool).

    Nicht so flexibel und minimal langsamer aber deutlich leichter zu verstehen ist da pugixml.
    http://pugixml.googlecode.com/svn/tags/latest/docs/quickstart.html
    Da hast du auch ein Beispiel, wie du ein xml einliest, weiter unten wie du über die Dom-Nodes iterierst.

    Aber vielleicht solltest du noch mal ne kurze C++-Grundlagensession einlegen. Wenn du nicht weißt was ein Objekt ist, fehlt dir einiges (oder dein Buch/Tutorial hat es nicht wirklich ordentlich vermittelt).



  • Hättest du kurz Zeit mal mit mir zu chatten ? hast du icq oder so?

    Hier mal mein komplettes Projekt:

    Unit1.cpp

    #include<iostream>
    #include<fstream>
    using namespace std;
    #include"Unit2.h"
    #include "rapidxml.hpp"
    #include "rapidxml_utils.hpp"
    #include "rapidxml_print.hpp"
    #include "rapidxml_iterators.hpp"
    
    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;
    
           ifstream los;
      los.open("Losungen.xml",ios::in);
    
        while(!los.eof())
        {
         string a;
         getline(los,a);
         cout<<a<<endl;
        }
    
            getchar();
            return 0;
    }
    

    Unit2.cpp

    #include<iostream>
    #include<fstream>
    #include<string>
    using namespace std;
    #include "Unit2.h"                                                              
    #include "rapidxml.hpp"
    #include "rapidxml_utils.hpp"
    #include "rapidxml_print.hpp"
    #include "rapidxml_iterators.hpp"
    
    Losung Losung_XML::zeigenSpruch(char Datum)
    {
     return feld[Datum];
    }
    
    rapidxml::xml_document<char> xmlfile;//Objekt anlegen
    xmlfile. parse(dateiinhalt);
    
    namespace rx = rapidxml;
    rx::file<> file("C:\Users\s08_e1fs\Desktop\Projekt_3_XMLauslesen\Losungen.xml");
    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();
    

    Unit2.h

    #include<iostream>
    #include<string>
    using namespace std;
    #include "rapidxml.hpp"
    #include "rapidxml_utils.hpp"
    #include "rapidxml_print.hpp"
    #include "rapidxml_iterators.hpp"
    
            struct Losung
       {
        string 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();
    
    };
    

    Ist aber wichtig sollte ich bis MOrgen haben :-((



  • pharao50 schrieb:

    ...rapidxml::xml_document<char> xmlfile;//Objekt anlegen
    xmlfile. parse(dateiinhalt);
    
    namespace rx = rapidxml;
    rx::file<> file("C:\Users\s08_e1fs\Desktop\Projekt_3_XMLauslesen\Losungen.xml");
    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();
    

    Steht das wirklich frei in der Quelldatei? So etwas gehört natürlich in eine Funktion, die du am Anfang des Programms aufrufen kannst.

    Zweitens brauchst du hier die ersten beiden Zeilen nicht, da du darunter nochmal eine komplettere Lösung hast.

    Und drittens: Du willst ja im Endeffekt alle <Losungen>-Blöcke einlesen, also benötigst du auch eine Schleife, die sie in deine Liste überträgt.

    PS: Und um schnell nach der Losung eines bestimmten Datums suchen zu können, ist eine map<string,Losung> besser geeignet als ein Array.

    PPS: Den Unterschied zwischen "char" (ein einzelne Zeichen) und "string" (eine Zeichenkette) solltest du dir auch nochmal ansehen 😉



  • eine while Schleife? Wie sage ich dieser, dass das Ende erreicht ist?
    Im ifstream geht das ja so:

    While(!dat.eof)
    {
    //Anweisungen...
    }

    Aber wie gehe ich vor wenn ich kein ifstream verwende?

    Was ist das?:

    map<string,Losung> besser geeignet als ein Array.



  • ich darf dir mal folgende Seite ans Herz legen:

    Für map:
    http://www.cplusplus.com/reference/stl/

    Für while:
    http://www.cplusplus.com/doc/tutorial/control/

    Für alle anderen Fragen als erste Anlaufstelle (evtl auch gezielter über google und dann ein ergebnis wählen was auf die BasisURL weist:)
    http://www.cplusplus.com/reference/

    Und dann gibts noch eine nette Literaturliste in der FAQ glaub ich ...



  • Also so dann?
    Sorry wenn ich überhaupt keinen Durchblick habe. Das ist für mich bisher noch alles neu.

    bool Losung_XML::ladenLosung(string dateiname)
    
    map<string,Losung>
    
     int i;
    
      for(i=366; i<367; i++)
      {
       namespace rx = rapidxml;
       rx::file<> file("C:\Users\s08_e1fs\Desktop\Projekt_3_XMLauslesen\Losungen.xml");
       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();
      }
    

Anmelden zum Antworten