Alles rund um die Programmierung mit Qt
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 22. Februar 2012 10:17
Hallo Leute,
ich muss in meinem Programm eine XML verarbeiten. Entweder über eine Datei:
Code: Alles auswählen
QString fileName = QFileDialog::getOpenFileName(this,
tr("XML-Datei"), "C:\\Home\\xml-files\\january", tr("XML-files(*.xml)"));
xml_File = new QFile(fileName);
if (!xml_File->open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::critical(this, "MYClass::slot_readXMLFile()", "Could not open *.xml", QMessageBox::Ok);
return;
}
QXmlStreamReader xml_Reader;
xml_Reader.setDevice(xml_File);
//..
Oder übers Web:
Code: Alles auswählen
QString destination_XML_URL = "www.xmls.com/myData.xml";
QUrl url = QUrl::fromEncoded( destination_XML_URL.toLocal8Bit() );
QNetworkRequest request(url);
QNetworkAccessManager url_network_access_manager;
QNetworkReply *url_network_reply = url_network_access_manager.get(request);
Klappt auch ganz gut. Aber ich würde die Ergebnisse QFile oder QNetworkReply gerne einer eigenen Methode übergeben. Mit dem QFile klappt ja pben schon..
Also meine Frage: Wie bekomme ich ein QNetworkReply *url_network_reply nach QIO_Device? Sodass ich
Code: Alles auswählen
QXmlStreamReader xml_Reader;
xml_Reader.setDevice(url_network_reply);
machen kann?
Mfg LesPaul
Zuletzt geändert von
lespaul am 14. März 2012 15:02, insgesamt 4-mal geändert.
Christian81
Beiträge: 7319 Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:
Beitrag
von Christian81 » 22. Februar 2012 10:55
QNetworkReply ist doch ein QIODevice - wo ist das Problem?
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 22. Februar 2012 13:21
Ja habe ich auch gemacht:
Code: Alles auswählen
void XMLRipper::fromInternet()
{
QString destination_XML_URL = "www.url.com/myData.xml";
QUrl url = QUrl::fromEncoded( destination_XML_URL.toLocal8Bit() );
QNetworkRequest request(url);
url_network_reply = url_network_access_manager.get(request);
transform_Raw_2_XML(url_network_reply);
}
void XMLRipper::fromFile()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("XML-Datei"), "C:\\path", tr("XML-files(*.xml)"));
xml_File = new QFile(fileName);
if (!xml_File->open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::critical(this, "CPOIDockWidget::fromFile()", "Could not open *.xml", QMessageBox::Ok);
return;
}
transform_Raw_2_XML(xml_File);
}
void XMLRipper::transform_Raw_2_XML(QIODevice * input_RAW)
{
xml_Reader.setDevice(input_RAW);
while (!xml_Reader.atEnd() && !xml_Reader.hasError()) {
/* Read next element.*/
QXmlStreamReader::TokenType token = xml_Reader.readNext();
//..usw. und so gut...
}
}
fromFile funzt!
fromInternet ist token = Invalid
und ich bekomme
Premature End of Document
?
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 22. Februar 2012 14:22
Könnte folgendes die Ursache sein?
Die lokale Datei hat
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
in der ersten Zeile.
Die XMl aus dem Web hat diese nicht. Dort geht es sofot mit den Tags los..
Wenn dies die Ursache ist, wie kann ich das beheben oder automatisch diese Zeile oben einfügen?
Ich danke!
Mfg LesPaul
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 6. März 2012 08:19
Morgen Leute,
mittels
versuche ich die empfangenen Bytes zu ermitteln, jedesmal 0.
Und
Code: Alles auswählen
url_network_reply->error() == QNetworkReply::NetworkError::NoError
Stimmt auch jedesmal, also kann es nicht am Proxy liegen, oder? Sonst stünde ja ein:
?
Gruß LesPaul
comdoxx
Beiträge: 12 Registriert: 23. Februar 2012 11:36
Wohnort: Bremen
Beitrag
von comdoxx » 6. März 2012 13:48
Die von christian verlinkte Doku erklärt doch alles genau.
Mit Deiner Methode ::fromInternet() kann es nicht klappen, da es sich nur um ein Reply-Objekt handelt, das aber noch keine Daten empfangen hat.
In der
http://doc.trolltech.com/4.7/qxmlstream ... al-parsing steht doch genau drin: "Since a QNetworkReply is a QIODevice, you connect its readyRead() signal to a custom slot, e.g. slotReadyRead() in the code snippet shown in the discussion for QNetworkAccessManager. In this slot, you read all available data with readAll() and pass it to the XML stream reader using addData(). Then you call your custom parsing function that reads the XML events from the reader."
Ich könnte wetten, dass Du keine slot-Methode erstellt hast.
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 12. März 2012 09:34
comdoxx hat geschrieben: Ich könnte wetten, dass Du keine slot-Methode erstellt hast.
Ich habe eine Slot-Methode erstellt, jedoch für den NetworkAccessManager. Der Manager emitted eine finished() und diese greift auch:
Code: Alles auswählen
connect(&url_network_access_manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(slot_disconnect2URL(QNetworkReply*)));
Jedoch ist mein NetworkReply 0 Byte groß?
Code: Alles auswählen
void XMLRipper::slot_disconnect2URL(QNetworkReply *data)
{
qint64 t_size1 = data->size();
qint64 t_size2 = data->readBufferSize();
if ( data->error() == QNetworkReply::NetworkError::NoError && t_size1 > 0 ) transform_Raw_2_XML(data);
else QMessageBox::critical(this, "XMLRipper::slot_disconnect2URL()", QString("Connection error :\n %1").arg(data->errorString()), QMessageBox::Ok);
}
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 12. März 2012 10:57
Und ich bekomme zusätzlich ein
QNetworkReply::ProtocolUnknownError 301 the Network Access API cannot honor the request because the protocol is not known
vom QNetworkReply.
comdoxx
Beiträge: 12 Registriert: 23. Februar 2012 11:36
Wohnort: Bremen
Beitrag
von comdoxx » 12. März 2012 12:55
Die Signal-/Slot-Geschichte läuft so, wenngleich Dein QXmlStreamReader die Daten noch nicht inkrementell zugestellt bekommt, was die Verarbeitung bei größeren XML-Dateien in Zusammenhang mit schmalerem Internet parallelisieren würde und somit schneller wäre.
Was den Fehler angeht: Endlich mal was aussagekräftiges. So aussagekräftig, dass man doch eigentlich nur die Aufforderung befolgen sollte: Es könnte hilfreich sein, im QNetworkRequest ein Protokoll anzugeben.
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 12. März 2012 15:24
comdoxx hat geschrieben: Es könnte hilfreich sein, im QNetworkRequest ein Protokoll anzugeben.
Meinst du so?
Code: Alles auswählen
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/xml");
Ich habe eine Datei aus dem Intranet genommen und nun gehts. Wenn ich jedoch eine Datei von ausserhalb referenziere und vorallem dynamisch generierte Datei, dann nicht mehr?
http://www.url.org/path/myXML.xml?value ... 6&value=20
Ich würde gerne auch value1, value2, value3 entsprechend ändern können...
comdoxx
Beiträge: 12 Registriert: 23. Februar 2012 11:36
Wohnort: Bremen
Beitrag
von comdoxx » 12. März 2012 15:58
Nein. Ich meine nicht den Header, sondern das Protokoll. Oder auch "Scheme" der QUrl. Vermutlich möchtest Du das Hypertext-Übertragungsprotokoll nutzen.
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 12. März 2012 16:30
Ahh ja, danke:
Das habe ich mal hinzugefügt und siehe da, der 301er ist weg und nun kommmt Fehler 3:
QNetworkReply::HostNotFoundError 3 the remote host name was not found (invalid hostname)
Code: Alles auswählen
void XMLRipper::setTarget(quint32 value1, quint32 value2, quint32 value3)
{
destination_XML_URL = QString("www.url.org/path/myXML.xml?value1=%1&value2=%2&value=%3").arg(value1).arg(value2).arg(value3);
//..dann später ....
QUrl url = QUrl::fromUserInput( destination_XML_URL );
}
Sollte ich das evtl. ohne die Qstring::arg().arg().arg() zusammenbauen?
Z.B. Fragmente mittels : QUrl::setQueryItems() ?? Oder würde das keine Auswirkung auf den Fehler haben?
comdoxx
Beiträge: 12 Registriert: 23. Februar 2012 11:36
Wohnort: Bremen
Beitrag
von comdoxx » 12. März 2012 16:58
Setze die URL doch einfach per String zusammen: url = QUrl("
http:// www.url.org ");
lespaul
Beiträge: 87 Registriert: 11. August 2011 10:07
Beitrag
von lespaul » 13. März 2012 09:09
Nope: Hilft leider nicht,
Code: Alles auswählen
QUrl url("http://www.aai.dfn.de/fileadmin/metadata/DFN-AAI-Test-metadata.xml"); gibt wieder Fehler 3.