How to download xml file and parse it using qt.



  • Hi,
    I am new to qt and got an assignement to download a xml file and parse it. I am abe to parse localy stored xml files using DOM, qt but don't know how to download xml file. Basically I will be having one xml file in server which I have to parse.
    So far I have thought of downloading it into a temporary location and parse it. Please let me know if there is any better way to do it.

    [edit : "pase" typo fixed in title, Eddy]



  • You might use "QNetworkAccessManager":http://doc.qt.nokia.com/stable/qnetworkaccessmanager.html to "get":http://doc.qt.nokia.com/stable/qnetworkaccessmanager.html#get your file. "QNetworkReply":http://doc.qt.nokia.com/stable/qnetworkreply.html is a QIODevice and thus can be directly passed to QDomDocument::setContent().



  • For parsing look to Classes from [[Doc:QtXml]] module, such as [[Doc:QXmlSimpleReader]] or [[Doc:QDomDocument]]


  • Moderators

    You can grab a working example from my QWebService library, file and class are named QWsdl. Of interest to you should be methods:
    395: @QWsdlPrivate::prepareFile()@ Checks whether the file is local or remote
    273: @QWsdl::fileReplyFinished(QNetworkReply *rply)@ Saves remote file on disk

    Link to "qwsdl.cpp":https://gitorious.org/qwebservice/qwebservice/blobs/master/QWebService/sources/qwsdl.cpp



  • Thanks for help, but I am facing few compilation error which I am not able to resolve. I am pasting my code here.

    @#include "qdom.h"
    #include "qFile.h"
    #include "qnetworkaccessmanager.h"
    #include "qurl.h"

    void fileReplyFinished(QNetworkReply* reply)
    {
    .............
    }

    my_func()
    {

    QNetworkAccessManager *manager = new QNetworkAccessManager();

    QObject::connect(manager, SIGNAL ( finished ( QNetworkReply* )),
    
                        this, SLOT ( fileReplyFinished ( QNetworkReply*   ))); 
    
    
    manager->get(QNetworkRequest(QUrl("http://my_website.com/my_profile.xml")));
    

    .........

    }

    @

    build errors:

    QTXML_parsing.cpp
    1>c:\my code\qtxml_parsing\qtxml_parsing\qtxml_parsing.cpp(98) : error C2665: 'QObject::connect' : none of the 2 overloads could convert all the argument types

    1>c:\my code\qtxml_parsing\qtxml_parsing\qtcore\qobject.h(198): could be 'bool QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)'

    1>c:\my code\qtxml_parsing\qtxml_parsing\qtcore\qobject.h(210): or 'bool QObject::connect(const QObject *,const char *,const char *,Qt::ConnectionType) const'

    1>while trying to match the argument list '(QNetworkAccessManager *, const char *, Updater *const , const char *)'

    1>c:\my code\qtxml_parsing\qtxml_parsing\qtxml_parsing.cpp(100) : error C2440: '<function-style-cast>' : cannot convert from 'QUrl' to 'QNetworkRequest'

    1>Source or target has incomplete type

    [Edit: Please, don't forget @-tags for code snippets /Vass]


  • Moderators

    First, wrap your code in '@' tags. Now, on with the problems:

    1. You are using QObject::connect() from which I gather, that your class is not QObject-derivative. In order to connect with fileReplyParsed(), you have to declare it a slot in your header file.
    2. More importantly, I see no reference to any class in your .cpp, yet you are using 'this' pointer... something is definitely missing in the code snippet you provided :)
    3. As for the last error - you should definitely avoid the standard constructor for QUrl - in Qt4, it does not work properly (it is fixed in Qt5), use one of the static methods instead (like QUrl::fromUserInput() etc.).


  • To use signals and slots your class has to be a (direct or indirect) subclass of QObject and it has to mention Q_OBJECT at the top of its declaration. In addition you are missing an include for QNetworkRequest.



  • Thanks for such a super fast reply.....:)

    1.> Yes, these functions are belong to "class my_class". Are you suggesting to derive my_calss from QObject?
    It seems we can't derive QObject in to my class. got few other build erros.

    builf error:

    c:\my code\qtxml_parsing\qtxml_parsing\qtxml_parsing.cpp(89) : error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'

    2.> You asked to declear a slot in header file, I have defined it in .cpp file "fileReplyFinished". Was that not enough?


  • Moderators

    [quote author="mady" date="1318486806"]Thanks for such a super fast reply.....:)

    1.> Yes, these functions are belong to "class my_class". Are you suggesting to derive my_calss from QObject?
    It seems we can't derive QObject in to my class. got few other build erros.

    builf error:

    c:\my code\qtxml_parsing\qtxml_parsing\qtxml_parsing.cpp(89) : error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'

    2.> You asked to declear a slot in header file, I have defined it in .cpp file "fileReplyFinished". Was that not enough?
    [/quote]

    Here are some basic details about signal-slot system: http://doc.qt.nokia.com/latest/signalsandslots.html#signals-and-slots

    It provides some small examples on how to declare everything and how does it work. Should solve most of your problems here. You can also take look into QWebService I've linked earlier, but it is somewhat more complicated, so might not be good for learning.

    To put it shortly:

    1. You've got to declare fileReplyFinished() as slot in header file, for example:
      @ protected slots:
      void fileReplyFinished(QNetworkReply *r);
      @

    2. Then in .cpp, remember to use the class prefix:
      @
      void my_class::fileReplyFinished(QNetworkReply *reply) {
      // ...
      }
      @

    3. In my_func(), you can use plain connect(), instead of QObject::connect() now that your class has the Q_OBJECT macro.



  • Thanks a lot......
    I am able to resolve that build error with your help. but now getting some wiered linking errors.... Seems l have to include some library for network programing. Please let me know if it is so. I am pasting linking errors those I am getting.

    QTXML_parsing.obj : error LNK2019: unresolved external symbol "public: __thiscall QNetworkRequest::~QNetworkRequest(void)" (??1QNetworkRequest@@QAE@XZ) referenced in function "public: void __thiscall Updater::GetLatestVersion(void)" (?GetLatestVersion@Updater@@QAEXXZ)
    1>QTXML_parsing.obj : error LNK2019: unresolved external symbol "public: class QNetworkReply * __thiscall QNetworkAccessManager::get(class QNetworkRequest const &)" (?get@QNetworkAccessManager@@QAEPAVQNetworkReply@@ABVQNetworkRequest@@@Z) referenced in function "public: void __thiscall Updater::GetLatestVersion(void)" (?GetLatestVersion@Updater@@QAEXXZ)
    1>QTXML_parsing.obj : error LNK2019: unresolved external symbol "public: __thiscall QNetworkRequest::QNetworkRequest(class QUrl const &)" (??0QNetworkRequest@@QAE@ABVQUrl@@@Z) referenced in function "public: void __thiscall Updater::GetLatestVersion(void)" (?GetLatestVersion@Updater@@QAEXXZ)
    1>QTXML_parsing.obj : error LNK2019: unresolved external symbol "public: static class QUrl __cdecl QUrl::fromUserInput(class QString const &)" (?fromUserInput@QUrl@@SA?AV1@ABVQString@@@Z) referenced in function "public: void __thiscall Updater::GetLatestVersion(void)" (?GetLatestVersion@Updater@@QAEXXZ)
    1>QTXML_parsing.obj : error LNK2019: unresolved external symbol "char const * __cdecl qFlagLocation(char const *)" (?qFlagLocation@@YAPBDPBD@Z) referenced in function "public: void __thiscall Updater::GetLatestVersion(void)" (?GetLatestVersion@Updater@@QAEXXZ)
    1>QTXML_parsing.obj : error LNK2019: unresolved external symbol "public: __thiscall QNetworkAccessManager::QNetworkAccessManager(class QObject *)" (??0QNetworkAccessManager@@QAE@PAVQObject@@@Z) referenced in function "public: void __thiscall Updater::GetLatestVersion(void)" (?GetLatestVersion@Updater@@QAEXXZ)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "private: static class QCoreApplication * QCoreApplication::self" (?self@QCoreApplication@@0PAV1@A)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Updater::metaObject(void)const " (?metaObject@Updater@@UBEPBUQMetaObject@@XZ)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall Updater::qt_metacast(char const *)" (?qt_metacast@Updater@@UAEPAXPBD@Z)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall Updater::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Updater@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Counter::metaObject(void)const " (?metaObject@Counter@@UBEPBUQMetaObject@@XZ)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall Counter::qt_metacast(char const *)" (?qt_metacast@Counter@@UAEPAXPBD@Z)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall Counter::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Counter@@UAEHW4Call@QMetaObject@@HPAPAX@Z)



  • It seems that you lack

    @
    QT += network
    @

    in your .pro file.

    [EDIT: it's QT not CONFIG]



  • Thanks for response.
    Now I am facing one new interesting linker error, BTW, I am using VS2008 + QT libraries for my tasks.

    When I am adding Q_OBJECT in my_class (since my class has slots) I am getting below linker error.

    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Updater::metaObject(void)const " (?metaObject@Updater@@UBEPBUQMetaObject@@XZ)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall Updater::qt_metacast(char const *)" (?qt_metacast@Updater@@UAEPAXPBD@Z)
    1>QTXML_parsing.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall Updater::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Updater@@UAEHW4Call@QMetaObject@@HPAPAX@Z)

    But If I remove Q_OBJECT I am not getting any linker error but my program is throwing an exception as below

    Object::connect: No such slot QObject::fileReplyFinished(QNetworkReply*) in c:\my code\qtxml_parsing\qtxml_parsing\qtxml_parsing.cpp:106
    QEventLoop: Cannot be used without QApplication
    QObject::connect: Cannot connect (null)::aboutToQuit() to QNativeWifiEngine::clo
    seHandle()



  • you have to moc the header file.

    1.) Add this to your custom build step settings:

    Command line: moc -o .\$(IntDir)\moc_$(InputName).cpp $(InputPath)
    
    Outputs: .\$(IntDir)\moc_$(InputName).cpp
    

    2.) Compile the header file

    3.) Include the generated moc file in your project.



  • It's usually sufficient (and needed) to re-run qmake and sometimes to do a rebuild of your project. Including the moc file into the project is not needed for qmake based projects, as this is handled by qmake automatically. qmake sometimes doesn't catch up .pro file changes and does not regenerate the Makefile automatically.



  • I wasn't sure if he is using qmake (he just mentioned VS2008). It would of course be the best way to go.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.