Seite 1 von 1

Xml Datei Parsen

Verfasst: 12. September 2011 10:55
von BamDenied
Hallo zusammen,

Ich bin noch recht unerfahren was C++ angeht und hoffe desswegen, dass ihr mir weiter helfen könnt.
Ich muss in C++ einen Konverter schreiben, der eine XML-Datei in ein intern verwendetes Dateiformat konvertiert.
Ich habe mich entschlossen di QT Bibliothek zum Parsen der Datei zu verwenden. Der erste schritt wäre ja die informationen aus dem XML-File herrauszufiltern. Ich habe mir das QtXml Module bereits angeguckt, doch weiß nicht wie ich die Datei am besten Parsen kann.

Kann mir eventuell einer von euch weiter helfen?

Vielen Dank!
Mark

Re: Xml Datei Parsen

Verfasst: 12. September 2011 11:09
von RHBaum
als erstes musst du dich entscheiden, welchen der beiden Wege fuers Parsen Du einschlagen willst ...
DOM-Parser oder SAX-Parser ?

DOM geht nur, wenn der Inhalt nicht allzugross ist und in den Hauptspeicher passt.
DOM ist einfacher zu begreifen und damit zu programmieren.

SAX ist ne komplett andere schiene (Eventbasiert) und haelt keine Daten. das musst selber machen.
SAX ist einfacher von der schnittstelle her, aber komplexer zu begreifen und anzuwenden. Musst halt mehr selber machen.
Wenn mans kann, ist SAX natuerlich performanter ... weil eigenImplementierungen meist auf den speziellen Fall optimierter sind.

Ciao ...

Re: Xml Datei Parsen

Verfasst: 12. September 2011 12:59
von BamDenied
Erst mal vielen Dank für die schnelle Antwort.

Ich denke mal das die SAX Methode für meine zwecke besser geeignet ist, da die Anforderrungen an den Konverter für hohe Preformance und große Dateien ausgelegt sein sollen.

Da mir dieser ganze Prozess des parsens ziemlich abstrackt vor kommt, wäre es eine große Hilfe zu wissen wie der Prozess abläuft.

Kleines Beispiel:
1. Xml-Datei wird eingelesen
2. Die Aktionen der Steuerelemente werden fest gelegt ( <tag)
3. Die ausgelesen Daten müssen Gruppiert werden
4. Die Ausgabe der XML-Informationen in einer Datei oder einem String

Dieser Ablauf ist wahrscheinlich nicht richtig, aber es wäre eine riesen Hilfe die einzelnen Teilprozesse in dem Prozess des parsens erläutert zu bekommen.

Vielen Dank für eure Hilfe
Mark

Re: Xml Datei Parsen

Verfasst: 12. September 2011 13:38
von franzf
Es gibt in den Qt-Sources unter examples/xml das saxbookmarks-example. Wäre ein guter Anfang :)

Re: Xml Datei Parsen

Verfasst: 12. September 2011 15:08
von RHBaum
Das prinzip des SAX parsers iss gar ned so komplex. heisst ja ned Umsonst "Simple Api for XML" ^^ :-)

Das ist nen Event parser !

Also grob beschrieben gehst du so vor:
Du Instanziierst den parser.
Du gibst Ihm einen Event / Errorhandler - aka du leitest von dem Event / Errorhandler -basis ab, und uebergibts die dem parser (setHandler).
Dann dann gibst ihm die Quelle (File oder datenstrom oder was anderes geeignetes ) und startest das Parsen (parse funktion )
Wichtig, das parsen kehrt erst wieder zurueck, wenn die Datei durch ist.

Das war fürs parsern erst mal alles :-)

Die Kunst ist nun, auf die Events zu hoeren, die der Eventhaendler wirft.

Da gibt es grob 3 Arten

startDocument / endDocument - erste/letzte Event was gefeuert wird, ... eigentlich ohne Inhalt, kann man aber gut fuer initialisieren und deinitialisieren verwenden.
startElement / endElement - wird geworfen wenn ein element haeder(tag) gelesen wird inklusive Attributes Auflistung/ element wieder geschlossen wurde (close Tag)
characters - wird fuer den text innerhalb der Tags geworfen (nicht fuer die Attribute) , da der Text 0-unendlich gross sein kann, und nicht garantiert wird, dass alles in den speicher kann, darf der Saxparser den text zerstueckeln, und mehrmals hintereinander characters aufrufen ... garantiert ist nur das die ZeichenBlöcke in folge kommen, und das die Summe bis zum ende des Tags (EndElement) gleich der Zeichen innerhalb der Tags ist. Also da musst selber sammeln.

Mit dem Rest musst dich erst mal ned beschaeftigen ...

Der Eventhaendler kann recht komplex werden ...
Ne gute Methode ist es, in eigene handler umzuleiten und die auf nen stack ablegen. Das oberste Element ist dann der aktuelle Context ...

Bei einfacheren Strukturen kommt man mit weniger Komplexitaet aus ...

Und wie franzf schon andeutete, Examples anschauen :-) Such auch mal nach Xerces-C (eigentlich der referenz XML-Parser, und 1. Adresse wenn man Qt frei bleiben will) und SAX ... da gibts auch ne ganze Menge Beispiele zu ...

Ciao ...

Re: Xml Datei Parsen

Verfasst: 13. September 2011 14:32
von BamDenied
Vielen Dank hat mich schon etwas weiter gebracht.

ich hab jetzt das Problem, dass ich die Atribute nich ausgelesen bekomme.
Wenn ich dich richtig verstanden habe macht man das mit dem StartElement Event?

in Meinem Handler steht zu StartElement Folgendes:

bool Handler::startElement(const QString& , const QString& ,const QString& qName, const QXmlAttributes& )
{
cout <<"StartElement: qname="<< qName.toStdString() << endl;
return true;
}

wie bekomme ich den jetzt die übergebenen Atribute raus?

Vielen dank
Mark

Re: Xml Datei Parsen

Verfasst: 13. September 2011 14:45
von franzf
wie bekomme ich den jetzt die übergebenen Atribute raus?
Schau dir Signatur und Doku an (HINT 4. Funktionsparameter HINT)

Re: Xml Datei Parsen

Verfasst: 2. Februar 2012 13:03
von BamDenied
Hallo zusammen,

das Projekt wurde erst mal zurückgestellt, doch jetzt ist es wieder da.^^

Ich habe einen SAX-Parser mit der QT-Bibliothe implementiert, jedoch habe ich das Problem, dass die überladenen Methoden meines eigenen Handlers beim Parsen der Datei nicht aufgerufen werden.
Vileicht könntet ihr euch das mal angucken:

Code: Alles auswählen

#include <QtXml>
#include "PersonalHandler.h"
#include "conio.h"

using namespace std;

int main(int argc, char** argv)
{   
    QFile file(argv[0]);
    QXmlSimpleReader reader;
    PersonalHandler* handler = new PersonalHandler;
    reader.setContentHandler(handler);
    QXmlInputSource inputSource(&file);
    reader.parse(inputSource);

    getch();  
}

Code: Alles auswählen

#pragma once
#include <QtXml>
using namespace std;

class PersonalHandler : public QXmlDefaultHandler
{
public:
    PersonalHandler();

    ~PersonalHandler(void);

    bool startElement(const QString &namespaceURI,
                      const QString &localName,
                      const QString &qName,
                      const QXmlAttributes &attributes);

    bool endElement(const QString &namespaceURI,
                    const QString &localName,
                    const QString &qName);

    bool characters(const QString &str);

};

Re: Xml Datei Parsen

Verfasst: 2. Februar 2012 14:52
von franzf
Evtl. Fehler in der XML-Datei? Was gibt parse() zurück? Installier mal nen ErrorHandler.

Re: Xml Datei Parsen

Verfasst: 2. Februar 2012 15:18
von BamDenied
In der XML-Datei ist auf jeden fall kein Fehler.

ich habe aber herrausgefunden, dass das QFile irgendwie nicht erstellt wird.

Code: Alles auswählen

    QString tmp("C:\Users\mbrings\Documents\test_example.xml");
    QFile file(tmp);   

    if(file.exists()==false)
    {
        cout<<"NEEEEEINN"<<endl; 
    }
Ergbnis ist NEEEEEINN .... Idee warum nich?
reader.parse() gibt ne 0 zurück

Re: Xml Datei Parsen

Verfasst: 2. Februar 2012 15:52
von BamDenied
okay es lag daran, dass die Datei nicht gefunden wurde. Die Backslash´s im absoluten Pfad wurden als Steuerelement interpretiert.

Re: Xml Datei Parsen

Verfasst: 5. Februar 2012 07:42
von mogel
BamDenied hat geschrieben:okay es lag daran, dass die Datei nicht gefunden wurde. Die Backslash´s im absoluten Pfad wurden als Steuerelement interpretiert.
http://developer.qt.nokia.com/doc/qt-4. ... f12a979eef
API hat geschrieben:QFile expects the file separator to be '/' regardless of operating system. The use of other separators (e.g., '\') is not supported.

Re: Xml Datei Parsen

Verfasst: 6. Februar 2012 15:19
von BamDenied
Danke.

Ich habe eine weitere Frage.

Wenn ich meine Datei Parse und er auf ein nicht vorhergesehene Syntax trifft (z.b. <--- zu beginn) bricht er mit dem Parsen ab.
Ich weiß, dass es die Methode reader.parseContinue() gibt, jedoch weiß ich nicht wie ich sie am besten verwende.
Wäre nett wenn ihr mir erklärt, wie er weiter parst nachdem er auf einen Fehler trifft.

Re: Xml Datei Parsen

Verfasst: 6. Februar 2012 16:13
von franzf
parseContinue() bringt dir in diesem Fall gar nichts. Aus der Doku geht klar hervor, dass das für inkrementelles Parsen gebraucht wird, wenn also eine InputSource nicht gleich das ganze XML-Dokument liefert.
Im Fehlerfall hilft nur eines: XML-Datei ausbessern.