Seite 1 von 2

XML von WWW oder Datei

Verfasst: 22. Februar 2012 10:17
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

Re: XML von WWW oder Datei

Verfasst: 22. Februar 2012 10:55
von Christian81
QNetworkReply ist doch ein QIODevice - wo ist das Problem?

Re: XML von WWW oder Datei

Verfasst: 22. Februar 2012 13:21
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
?

Re: XML von WWW oder Datei

Verfasst: 22. Februar 2012 14:22
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

Re: XML von WWW oder Datei

Verfasst: 22. Februar 2012 17:42
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

Re: XML von WWW oder Datei

Verfasst: 6. März 2012 08:19
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

Re: XML von WWW oder Datei

Verfasst: 6. März 2012 13:48
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.

Re: XML von WWW oder Datei

Verfasst: 12. März 2012 09:34
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);
}

Re: XML von WWW oder Datei

Verfasst: 12. März 2012 10:57
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.

Re: XML von WWW oder Datei

Verfasst: 12. März 2012 12:55
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.

Re: XML von WWW oder Datei

Verfasst: 12. März 2012 15:24
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...

Re: XML von WWW oder Datei

Verfasst: 12. März 2012 15:58
von comdoxx
Nein. Ich meine nicht den Header, sondern das Protokoll. Oder auch "Scheme" der QUrl. Vermutlich möchtest Du das Hypertext-Übertragungsprotokoll nutzen.

Re: XML von WWW oder Datei

Verfasst: 12. März 2012 16:30
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?

Re: XML von WWW oder Datei

Verfasst: 12. März 2012 16:58
von comdoxx
Setze die URL doch einfach per String zusammen: url = QUrl("http://www.url.org");

Re: XML von WWW oder Datei

Verfasst: 13. März 2012 09:09
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.