Seite 1 von 1

XML howto

Verfasst: 24. April 2006 17:08
von webcd
Kann mir jemand erklären, wie QtXml funktioniert?
ich steige da nicht ganz hinter.

Ich will http://www.wellness-motorik.de/WebCD/produkte2.xml (nicht komplett korrekt) einlesen und dann nach gruppen sortiert verarbeiten, kann mir jemand mal einen Grundansatz erklären?

Verfasst: 24. April 2006 17:27
von patrik08
das beispiel qt4 liest die tag aus....
qt4\examples\xml\dombookmarks ...

obwohl ich das file http://www.wellness-motorik.de/WebCD/produkte2.xml (nicht utf8 conform) man koennte es lesen fast wie eine shop liste ... und mit xslt direkt in eine mini (qt sqlite) datenbank einfugen.... (lese qt + excel in diesem forum +3000 abrufe.... das excel dort ist auch xml...)

Verfasst: 24. April 2006 17:52
von webcd
es ist auch eine Shopliste, mit allen Produkten, verteilt in Kategorien
nur soll es jeden programmstart mit XML over HTTP geupdatet werden.

auf beispiel DOMBookmarks bin ich auch schon gestoßen, nur verstehe ich es nicht

Verfasst: 24. April 2006 18:31
von patrik08
webcd hat geschrieben:auf beispiel DOMBookmarks bin ich auch schon gestoßen, nur verstehe ich es nicht
ich will ja qt nicht schlecht machen ... im gegenteil es ist super fuer widget button farbe ecc.. mac / linux / win ... aber mit xml & http verarbeitung bin ich sicher dass ich es einfacher & vor allem schneller al qt mache...

die datei holen...

Code: Alles auswählen

/*  #define _USER_AGENT_CURL_APPS "Mozilla/5.0 (Windows; U; Windows NT 5.1; it-CH; rv:1.7.12) Gecko/20050919 Firefox/1.0.7"
 ein cookie file und ein tmp file configurieren ... timeout auf 5-10 sekunden setzen oder noch weinger...  */
/*  Warning get local file contents or remote file contents by curl  */
QString Config::file_get_contents(QString fullFileName)
{
        QString inside = "";
        if (fullFileName.contains("https://", Qt::CaseInsensitive)) { 
        inside = "No build support to https protocoll";
        return inside;
        } 

       if ( this->IsNetFile( fullFileName ) )
       {
        file_put_contents(www_net_file,"");  /* remove last action if exist */
           
         if ( fullFileName.contains("webdav://", Qt::CaseInsensitive )) {
         #ifndef GRABCONFIGPASS
         #define GRABCONFIGPASS
         #endif
         }
         
         char *localfile = append( qt2char( cachedir ) , c_www_net_file );
         char *cookiefile = append( qt2char( cachedir ) , c_www_cookie_file );
         char *url = qt2char( fullFileName );
         
            CURL *curl_handle;
            FILE *outfile;
            curl_global_init(CURL_GLOBAL_ALL);     
            curl_global_init(CURL_GLOBAL_ALL);
            curl_handle = curl_easy_init();
            outfile = fopen(localfile, "w"); 
 
                if (outfile!=NULL) {
                    /* CURLOPT_COOKIE and must have CURLOPT_COOKIEJAR char * (file to write same as php)   */
                    curl_easy_setopt(curl_handle, CURLOPT_URL, url);
                    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, TRUE);
                    curl_easy_setopt(curl_handle, CURLOPT_COOKIEJAR, cookiefile );
                    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION , 1);
                    curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS , 5);
                    curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT , timeoutsec );
                    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, c_user_agent );
                    curl_easy_setopt(curl_handle, CURLOPT_FILE, outfile);   
                    
                     if (curl_easy_perform(curl_handle)==CURLE_OK) {
                         fclose(outfile);
                         
                            QFile filecurl(www_net_file);
                             if (filecurl.size() > 5) {
                               curlerrormsg = "ok_success";  
                             } else {
                              curlerrormsg = "Error time out to get remote file"+QString( "%1" ).arg( getExactTime() ); 
                             }
                             
                     }  else {
                     curlerrormsg = "Error time out to get remote file"+QString( "%1" ).arg( getExactTime() );
                     file_put_contents(www_net_file,"");
                     }                         
                } 
       /* return grab result from local file */
      return file_get_contents(www_net_file);
      }

    
    
     
    /*  ok is a fake normal local file init .....  */
    QFile file(fullFileName); 
    if (file.exists()) {
                if (file.open(QFile::ReadOnly | QFile::Text)) {
                  inside =file.readAll();
                  file.close();
                  errormsg = "ok_success";
                } else {
                 inside = "no_open_file";
                }
    } else {
    inside = "no_file";  
    }
    
   return inside;
}
die datei ins richtige utf8 bringen .... mit xslt (wie beispiel xml excel zu sql) das xml in einen sqlite dump konvertieren....
dein converter ist sicher noch kleiner ... da nur eine tabelle....

das file in eine ram sqlite infuegen ....

in etwa so....

Code: Alles auswählen


bool Gui_Main::ConnectDB()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");
    if (!db.open()) {
        msgb->critical( this , "Cannot open database",
                     "Unable to establish a database connection.\n"
                     "This example needs SQLite support. Please read "
                     "the Qt SQL driver documentation for information how "
                     "to build it.\n\n"
                     "Click Cancel to exit.", msgb->Cancel , msgb->NoButton);
     return false;
    }
    int countnr = 0;
    QString fileinserts = QString::fromUtf8(":/root/db/insert_dump.sql");
    QSqlQuery query;
    QString alls ="";
    QString inside;
    QFile file( fileinserts );
    QTextStream in(&file);
   
        while (!in.atEnd()) {
         ++countnr;
         inside = in.readLine(0);  /* line by line (); */
           
            if (inside.size() > 1 and !inside.startsWith("#", Qt::CaseInsensitive) )  {
               
                if (alls.size() > 0) {
                /* nicht  erste zeile */
                 if (! query.exec(inside.replace(QString(";"), QString(""))) ) {
                 return false;
                 }
                alls = alls+"\n"+ inside;
                } else {
                /*  erste zeile */
                if (! query.exec(inside.replace(QString(";"), QString(""))) ) {
                 return false;
                 }
                alls = inside;
                }
            }
        }
       
  textdb =alls; 
 return true;   
}
wie die sql edit auto methode updaten...
die daten extraieren in sql oder direkter mysql replace dump schreiben... ... weiss ja nicht was der server hat..

mit curl method post user pass .. oder webdav zum server senden...

die libs libcurl / libxml2 / libxslt sind in weniger als 30 minuten kompliliert... mit minimal sys von mingw.... und gehen super auf mac linux & win ... und wenn der shop mal andere daten hat must du nur den converter felder dazu oder weg...

Verfasst: 24. April 2006 21:11
von webcd
verstehe ich es richtig, dass dazu noch eine Datenbank benötigt wird?
Wenn ja, dann ist dies leider keine Lösung für mich, da ich die Datei jedes mal neu abholen muss und in der Anwendung benutzen.
Programme wie z.B. eine Datenbank kann ich da nicht nutzen :oops:

Die Http hol Funktion/Klasse habe ich schon, sie ist direkt in meinen Splash/Loading Screen integriert (mit Verbunden... &Prozent) mir geht es jetzt nur noch darum die xml Daten in die App. zu integrieren.

Da ich Qt Neuling bin, kennne ich leider auch keine geeigneten Container dafür.

Verfasst: 24. April 2006 21:42
von patrik08
webcd hat geschrieben:verstehe ich es richtig, dass dazu noch eine Datenbank benötigt wird?
Wenn ja, dann ist dies leider keine Lösung für mich, da ich die Datei jedes dafür.
gut schreibe ... jedes feld mit mit passendes name einzeln auf... :D

ich arbeite mit der RAM datenbank. sqlite3.. db.setDatabaseName(":memory:"); /* ohne password ohne user ... lauf sogar nur auf cd ... habe heute eine demo gemacht beim kunde... */
das beispiel qt4\examples\sql\cachedtable\release macht ja bereit der job der du willst... :wink: (wen du qt ohne sqlite uebersetz hast ... kannst du dein fertiges programm nicht sehen...)

must du nur die ram db exportieren zu server beim class destruct...

Verfasst: 24. April 2006 23:31
von patrik08
dass geht.... im andere ist file open.... & close nicht drinnen.....
in weniger als 1 sekunden macht er bis zu 2000 neue zeilen...

Code: Alles auswählen


static bool db_ram()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");
    if (!db.open()) {
        QMessageBox::critical(0, "Cannot open database",
                     "Unable to establish a database connection.\n"
                     "This example needs SQLite support. Please read "
                     "the Qt SQL driver documentation for information how "
                     "to build it.\n\n"
                     "Click Cancel to exit.", QMessageBox::Cancel,
                     QMessageBox::NoButton);
        return false;
    }
    
    QSqlQuery query;
    QString inside;
    /*  sqldump als resource datei ... oder auch ein sql dump mit http://sqlitebrowser.sourceforge.net/ */
    QString sqlinsert = QString::fromUtf8(":/root/db/insert_dump.sql");
    QFile file( sqlinsert );
    
    if (!file.open(QFile::ReadOnly | QFile::Text)) {
    return false;
    }
    QTextStream sw(&file);
       while (!sw.atEnd()) { 
           inside = sw.readLine(0);
             if (inside.size() > 1 and !inside.startsWith("#", Qt::CaseInsensitive) and !inside.startsWith("beginn", Qt::CaseInsensitive) and !inside.startsWith("commit", Qt::CaseInsensitive) )  {
                query.exec(inside.replace(QString(";"), QString("")));
             }
       } 
    file.close();
    return true;
}


tabelle auswahl.... und editieren....

Code: Alles auswählen


void Gui_Main::PaintCombox()
{
        if (!db_ram()) {
        msgb->information( this ,  "Database error!", "Error connect ram db!" );
        }
       QSqlQuery query;
       QString current;
       QString tablequery ="SELECT name  FROM sqlite_master WHERE type!='meta' AND sql NOT NULL ORDER BY name";
       query.exec(tablequery);
       db_option->clear();
        /* combox => db_option NAME */
       db_option->addItem("Select Your Table:");
       while (query.next()) {
            current = query.value(0).toString();
           db_option->addItem(current);
        }
       connect(db_option, SIGNAL(activated(const QString &)), this , SLOT(ShowTable(const QString &)));
}

void Gui_Main::ShowTable(const QString t)
{
        if (!db_ram()) {
            msgb->information( this ,  "Database error!", "Error connect ram db!" );
        }
        if ( !t.startsWith("select", Qt::CaseInsensitive) ) {
        sqlmodel = new QSqlTableModel(this);
        sqlmodel->setTable(t);
        sqlmodel->setEditStrategy(sqlmodel->OnManualSubmit);
        sqlmodel->select();
        multitable->setModel(sqlmodel);
        }
}

mit wenig code viele tabelle updaten....