Xml Datei Parsen

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
BamDenied
Beiträge: 21
Registriert: 6. September 2011 10:54

Xml Datei Parsen

Beitrag 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
Zuletzt geändert von BamDenied am 12. September 2011 11:49, insgesamt 1-mal geändert.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Xml Datei Parsen

Beitrag 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 ...
BamDenied
Beiträge: 21
Registriert: 6. September 2011 10:54

Re: Xml Datei Parsen

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Xml Datei Parsen

Beitrag von franzf »

Es gibt in den Qt-Sources unter examples/xml das saxbookmarks-example. Wäre ein guter Anfang :)
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Xml Datei Parsen

Beitrag 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 ...
BamDenied
Beiträge: 21
Registriert: 6. September 2011 10:54

Re: Xml Datei Parsen

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Xml Datei Parsen

Beitrag von franzf »

wie bekomme ich den jetzt die übergebenen Atribute raus?
Schau dir Signatur und Doku an (HINT 4. Funktionsparameter HINT)
BamDenied
Beiträge: 21
Registriert: 6. September 2011 10:54

Re: Xml Datei Parsen

Beitrag 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);

};
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Xml Datei Parsen

Beitrag von franzf »

Evtl. Fehler in der XML-Datei? Was gibt parse() zurück? Installier mal nen ErrorHandler.
BamDenied
Beiträge: 21
Registriert: 6. September 2011 10:54

Re: Xml Datei Parsen

Beitrag 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
BamDenied
Beiträge: 21
Registriert: 6. September 2011 10:54

Re: Xml Datei Parsen

Beitrag von BamDenied »

okay es lag daran, dass die Datei nicht gefunden wurde. Die Backslash´s im absoluten Pfad wurden als Steuerelement interpretiert.
mogel
Beiträge: 4
Registriert: 31. Januar 2012 08:17

Re: Xml Datei Parsen

Beitrag 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.
BamDenied
Beiträge: 21
Registriert: 6. September 2011 10:54

Re: Xml Datei Parsen

Beitrag 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.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Xml Datei Parsen

Beitrag 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.
Antworten