3

I have strange issue with Qt QXmlStreamReader. I'am trying to parse simple document (note: it is generated using QXmlStreamWriter):

<?xml version="1.0" encoding="UTF-8"?>
<tex>
    <used_by/>
    <facade>
        <tags>
            <town_related></town_related>
            <zone_related></zone_related>
            <visual_related></visual_related>
            <kind_related></kind_related>
            <other>flamingo</other>
        </tags>
        <additional_textures>
            <id>flamingo_top.psd</id>
        </additional_textures>
    </facade>
</tex>

Using this code:

QFile file(filename);
if (file.open(QFile::ReadOnly | QFile::Text))
{
    QXmlStreamReader xmlReader(&file);

    while (xmlReader.readNextStartElement())
    {
        /* same issue when uncommented: 
        if (xmlReader.name() == "tex")
            t->readXml(xmlReader);//parse texture
        else*/
            xmlReader.skipCurrentElement();
    }

    if (xmlReader.hasError())
        emit reportError(xmlReader.errorString());
}
...

And it always reports error "Premature end of document". Why? When debbuging, it seems, to all elements are parsed or skipped correctly.

  • I suspect the issue is you're never checking that you've reached the end of the document. Try calling [atEnd()](http://doc.qt.io/qt-5/qxmlstreamreader.html#atEnd) before reading the next element. – MrEricSir Sep 21 '17 at 15:54
  • Thank you for the comment. But I think, this is not the solution. If I use atEnd() in while loop condition, result is same, unfortunatelly. – Vladimir Semotan Sep 21 '17 at 20:21
  • I see exactly the same issue in Qt 5.11.1, looks like a bug to me, should we report it? – codeling Sep 14 '18 at 10:17

1 Answers1

3

I verified the behavior of your code. Indeed, it seems that readNextStartElement() does not correctly check for end of document. It only checks for start/end element to return its value, so if reading past the end of document, its internal call to readNext raises "premature end".

For a quick fix try checking for end of document yourself using readNext(), eg.:

    while (!xml.atEnd()) {
        if (xml.readNext() != QXmlStreamReader::EndDocument) {
            if (xml.isStartElement())
                std::cout << qPrintable(xml.name().toString()) << std::endl;
        }
    }

    if (xml.hasError())
        std::cout << (xml.errorString().toUtf8().constData()) << std::endl;
pe3k
  • 796
  • 5
  • 15