Results 1 to 4 of 4

Thread: QXmlStreamReader and PrematureEndOfDocumentError

  1. #1
    Join Date
    Apr 2008
    Location
    Russia, Moscow
    Posts
    86
    Thanks
    2
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4

    Question QXmlStreamReader and PrematureEndOfDocumentError

    I have this code like this:

    Qt Code:
    1. bool XmlSpoListParser::read()
    2. {
    3. while (!atEnd()) {
    4. readNext();
    5.  
    6. if (isStartElement()) {
    7. if (name() == QLatin1String("Tag") && attributes().value(QLatin1String("version")) == QLatin1String("1.0")) {
    8. readSomething1();
    9. break;
    10. } else {
    11. raiseError(QObject::tr("The file is not an Tag version 1.0 file."));
    12. break;
    13. }
    14. }
    15. if (hasError() && onError()) {
    16. break;
    17. }
    18. }
    19.  
    20. return !error();
    21. }
    22.  
    23. bool XmlSpoListParser::onError()
    24. {
    25. if (error() == QXmlStreamReader::PrematureEndOfDocumentError) {
    26. appendMoreData();
    27. return false;
    28. } else {
    29. qDebug() << errorString();
    30. return true;
    31. }
    32. }
    33.  
    34. void XmlSpoListParser::appendMoreData()
    35. {
    36. //???
    37. }
    38.  
    39. void XmlSpoListParser::readSomething1()
    40. {
    41. while (!(isEndElement() && name() == QLatin1String("Tag2")) && !atEnd()) {
    42. readNext();
    43. if (isStartElement()) {
    44. if (name() == QLatin1String("Tag3")) {
    45. readSomething2();
    46. } else {
    47. skipSubTree();
    48. }
    49. }
    50. if (hasError() && onError()) {
    51. break;
    52. }
    53. }
    54. }
    55.  
    56. void XmlSpoListParser::readSomething2()
    57. {
    58. while (!(isEndElement() && name() == QLatin1String("Tag3")) && !atEnd()) {
    59. readNext();
    60. if (isStartElement()) {
    61. if (name() == QLatin1String("Tag4")) {
    62. readSomething3();
    63. } else {
    64. skipSubTree();
    65. }
    66. }
    67. if (hasError() && onError()) {
    68. break;
    69. }
    70. }
    71. }
    To copy to clipboard, switch view to plain text mode 

    How i can wait data from socket when error PrematureEndOfDocumentError occured from readSomething2() method (for example)? I wan't call addData() to parser and return back to method readSomething1() after new data arrived. What i must do, create additional QEventLoop in method appendMoreData, or use infinite while(1) with QApplication::processEvents() or what?

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QXmlStreamReader and PrematureEndOfDocumentError

    Quoting QXmlStreamReader docs:
    Incremental parsing

    QXmlStreamReader is an incremental parser. It can handle the case where the document can't be parsed all at once because it arrives in chunks (e.g. from multiple files, or over a network connection). When the reader runs out of data before the complete document has been parsed, it reports a PrematureEndOfDocumentError. When more data arrives, either because of a call to addData() or because more data is available through the network device(), the reader recovers from the PrematureEndOfDocumentError error and continues parsing the new data with the next call to readNext().

    For example, if you read data from the network using QHttp, you would connect its readyRead() signal to a custom slot. 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.
    J-P Nurmi

  3. #3
    Join Date
    Apr 2008
    Location
    Russia, Moscow
    Posts
    86
    Thanks
    2
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4

    Default Re: QXmlStreamReader and PrematureEndOfDocumentError

    When more data arrives, either because of a call to addData() or because more data is available through the network device(), the reader recovers from the PrematureEndOfDocumentError error and continues parsing the new data with the next call to readNext().
    I test QBuffer and QFile as device() and each time when i try use addData() i get error in console about using device(). I don't know, may be if device has been socket may all be allright, but i don't think what this solved problem when parser must return execute after error() with PrematureEndOfDucumentError. error() just exit from all while()'s and no chance restore parsing.

    For example, if you read data from the network using QHttp, you would connect its readyRead() signal to a custom slot. 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.
    How readyRead() can help restore parser execute from last context? For this situation we must have while(1) for wait readyReady or reparsing previous xml with new data from beginning.

  4. #4
    Join Date
    Apr 2008
    Location
    Russia, Moscow
    Posts
    86
    Thanks
    2
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4

    Default Re: QXmlStreamReader and PrematureEndOfDocumentError

    I checkout parser with socket. Documentation is lie or i do something wrong:

    For example, if you read data from the network using QHttp, you would connect its readyRead() signal to a custom slot. 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.
    When i run program i get:

    Qt Code:
    1. QXmlStreamReader: addData() with device()
    To copy to clipboard, switch view to plain text mode 

    in console. Inside parser i set device as:

    Qt Code:
    1. void MainWindow::onConnectionEstablished() {
    2. qDebug() << "Connection established!";
    3. if (!reader.read(socket)) {
    4. ...
    5. bool XmlSpoListParser::read(QIODevice *device) {
    6. setDevice(device);
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void MainWindow::readIncomingData()
    2. {
    3. qDebug() << "Get: " << socket->size() << " bytes.";
    4. reader.addData(socket->readAll());
    5. }
    To copy to clipboard, switch view to plain text mode 

    If i remove setDevice() and write this code all work fine:

    Qt Code:
    1. void MainWindow::readIncomingData() {
    2. qDebug() << "Get: " << socket->size() << " bytes.";
    3. reader.addData(socket->readAll());
    4. reader.loop.quit();
    5. }
    6. ...
    7. class XmlSpoListParser : public QXmlStreamReader {
    8. public:
    9. XmlSpoListParser();
    10. bool read(QIODevice *);
    11. bool read();
    12. QEventLoop loop;
    13.  
    14. ...
    15. void XmlSpoListParser::appendMoreData() {
    16. loop.exec();
    17. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. bool XmlSpoListParser::onError() {
    2. if (error() == QXmlStreamReader::PrematureEndOfDocumentError) {
    3. appendMoreData();
    4. return false;
    5. } else {
    6. qDebug() << errorString();
    7. return true;
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    But code with QEventLoop looks ugly. How right?

Similar Threads

  1. Reading and rereading a file with QXmlStreamReader
    By TheRonin in forum Qt Programming
    Replies: 14
    Last Post: 30th April 2015, 14:04
  2. Mysterious QXMLStreamReader parsing behavior
    By ym1206 in forum Qt Programming
    Replies: 3
    Last Post: 14th June 2010, 19:56
  3. how QXmlStreamReader parse QString
    By SamSong in forum Qt Programming
    Replies: 2
    Last Post: 6th November 2009, 14:56
  4. QXmlStreamReader error on first line?
    By warry in forum Qt Programming
    Replies: 2
    Last Post: 13th August 2008, 14:20
  5. QXmlStreamReader rewind
    By bunjee in forum Qt Programming
    Replies: 3
    Last Post: 13th April 2008, 08:00

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.