QtNetwork: загрузите файл xml и прочитайте его содержимое

У меня есть приложение Qt, в котором я пытаюсь загрузить файл XML с сервера, а затем прочитать содержимое файла. К сожалению, я не могу загрузить содержимое загруженного файла в файл QDomDocument.

Это то, что я пробовал

QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileIsReady(QNetworkReply*)) );
manager->get(QNetworkRequest(QUrl("http://example.com/file.xml")));


fileIsReady(QNetworkReply *reply){

    QTemporaryFile tempFile;
    if(tempFile.open()){
        tempFile.write(reply->readAll());
        QDomDocument versionXML;
        QDomElement root;

        if(!versionXML.setContent(&tempFile)){
            qDebug() << "failed to load version file" << endl;
        }
        else{
            root=versionXML.firstChildElement();
            //...
        }

    }

}

Как я могу этого добиться?


person testus    schedule 28.01.2015    source источник
comment
Убедитесь, что вы сбрасываете данные и возвращаетесь к 0 перед настройкой содержимого.   -  person alediaferia    schedule 28.01.2015
comment
Кроме того, QDomDocument::setContent(QIODevice * dev, bool namespaceProcessing, QString * errorMsg = 0, int * errorLine = 0, int * errorColumn = 0) дает простой способ узнать фактическое сообщение об ошибке...   -  person alediaferia    schedule 28.01.2015
comment
@alediaferia, можете ли вы сказать мне, что вы имеете в виду под сбросом данных?   -  person testus    schedule 28.01.2015
comment
Убедитесь, что данные, которые вы записываете из reply->readAll() во временный файл, действительно записываются в файл, а не просто буферизируются в памяти. Этого можно добиться, вызвав tempFile.flush() перед настройкой содержимого. Кроме того, QDomDocument::setContent не дает никаких советов относительно того, как он использует QIODevice*, который вы передаете, поэтому вам лучше tempFile.seek(0) раньше, чтобы убедиться, что QDomDocument действительно читает с начала файла.   -  person alediaferia    schedule 28.01.2015
comment
Обратите внимание, что временный файл на самом деле не нужен. QNetworkReply наследуется от QIODevice, так что вы можете просто сделать versionXML.setContent(reply).   -  person Dan Milburn    schedule 28.01.2015
comment
В любом случае, здесь есть что проверить. Вам также необходимо проверить, получаете ли вы правильный ответ от сервера. В любом случае, я настоятельно рекомендую вам распечатать сообщение об ошибке.   -  person alediaferia    schedule 28.01.2015


Ответы (1)


Я думаю, что потоковые интерфейсы немного сложны в использовании, когда вы новичок в Qt. Если у вас нет сверхбольших загрузок, которые помещаются в ОЗУ, просто используйте QByteArray.

fileIsReady(QNetworkReply *reply){
    QByteArray data = reply->readAll();
    qDebug() << "XML download size:" << data.size() << "bytes";
    qDebug() << QString::​fromUtf8(data);

    QDomDocument versionXML;

    if(!versionXML.setContent(data))
    {
        qWarning() << "Failed to parse XML";
    }

    // ...
}
person Simon Warta    schedule 28.01.2015
comment
Я пробовал это, но каждый раз получаю Размер загрузки XML: 226 байт. Не удалось проанализировать QML. Даже если я ссылаюсь на несуществующий файл, я получаю тот же размер загрузки XML. Первая часть manager->get(QNetworkRequest(QUrl("http://example.com/file.xml"))); верна? - person testus; 28.01.2015
comment
Хорошо, тогда посмотрите, что это за 226 байт. Смотрите мой отредактированный ответ. - person Simon Warta; 28.01.2015
comment
‹head›‹title›Неприемлемо!‹/title›‹/head›‹body›‹h1›Неприемлемо!‹/h1›‹p›Не удалось найти подходящее представление запрошенного ресурса на этом сервере . Эта ошибка была сгенерирована Mod_Security.‹/p›‹/body›‹/html› Если я скопирую ту же ссылку, которую я вставил в manager в веб-браузере, я увижу свой файл XML. - person testus; 28.01.2015
comment
Похоже, вам нужно установить правильный заголовок Accept в запросе. en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields - person Simon Warta; 28.01.2015
comment
получил это, используя этот ответ stackoverflow.com/questions/14416786/ - person testus; 28.01.2015