XML von WWW oder Datei

Alles rund um die Programmierung mit Qt
lespaul
Beiträge: 87
Registriert: 11. August 2011 10:07

XML von WWW oder Datei

Beitrag von lespaul »

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:

Re: XML von WWW oder Datei

Beitrag von Christian81 »

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

Re: XML von WWW oder Datei

Beitrag von lespaul »

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

Re: XML von WWW oder Datei

Beitrag von lespaul »

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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: XML von WWW oder Datei

Beitrag von Christian81 »

Ein QNetWorkReply muss nicht zwingend alle Daten haben - und QXmlStreamReader kann sogar damit umgehen... Doku mal wieder: http://doc.trolltech.com/4.7/qxmlstream ... al-parsing
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
lespaul
Beiträge: 87
Registriert: 11. August 2011 10:07

Re: XML von WWW oder Datei

Beitrag von lespaul »

Morgen Leute,

mittels

Code: Alles auswählen

qint64 t_size = url_network_reply->readBufferSize();
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:

Code: Alles auswählen

QNetworkReply::ProxyConnectionRefusedError
?

Gruß LesPaul
comdoxx
Beiträge: 12
Registriert: 23. Februar 2012 11:36
Wohnort: Bremen

Re: XML von WWW oder Datei

Beitrag von comdoxx »

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

Re: XML von WWW oder Datei

Beitrag von lespaul »

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

Re: XML von WWW oder Datei

Beitrag von lespaul »

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

Re: XML von WWW oder Datei

Beitrag von comdoxx »

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

Re: XML von WWW oder Datei

Beitrag von lespaul »

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

Re: XML von WWW oder Datei

Beitrag von comdoxx »

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

Re: XML von WWW oder Datei

Beitrag von lespaul »

Ahh ja, danke:

Code: Alles auswählen

url.setScheme("http");
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

Re: XML von WWW oder Datei

Beitrag von comdoxx »

Setze die URL doch einfach per String zusammen: url = QUrl("http://www.url.org");
lespaul
Beiträge: 87
Registriert: 11. August 2011 10:07

Re: XML von WWW oder Datei

Beitrag von lespaul »

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