[Qt-interest] QXmlStreamReader: Usage of readNextStartElement()?

Oliver.Knoll at comit.ch Oliver.Knoll at comit.ch
Tue Dec 21 18:06:40 CET 2010


Hi,

I am having difficulties understanding the proper usage of QXmlStreamReader#readNextStartElement():

When I have the following code snippet which should print out all element names and attributes:

  QXmlStreamReader streamReader(&file);
  while (streamReader.readNextStartElement()) {

    qDebug("name: %s", qPrintable(streamReader.name().toString()));
    QXmlStreamAttributes attributes = streamReader.attributes();
    foreach(QXmlStreamAttribute attribute, attributes) {
      qDebug("    Attribute: name: %s, value: %s", qPrintable(attribute.name().toString()), qPrintable(attribute.value().toString()));
    }

  }

And I have e.g.

  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE screenie>
  <foo version="1.0">
    <bar enabled="true" bgcolor="#ffffff"/>
    <foobar baz="42"/>
    <rabarber>Some text</rabarber>
  </foo>

I only get:

name: foo
    Attribute: name: version, value: 1.0
name: bar
    Attribute: name: enabled, value: true
    Attribute: name: bgcolor, value: #ffffff

That is the parsing seems to stop after the 2nd element <bar .../>.

>From the Qt docs http://doc.trolltech.com/4.7/qxmlstreamreader.html#readNextStartElement: "Reads until the next start element within the current element. [...]The current element is the element matching the most recently parsed start element of which a matching end element has not yet been reached."

So let's assume that <foo> - the outermost "start element" as it seems to me - is the "current element", should I not get also the <foobar /> and <rababer /> elements? What really twists my mind is that I /do/ get the <bar> element, but why not the <foobar> and <rabarber> elements, which are at the same level as <bar>? So the time when readNextStartElement seems to stop is a mistery to me...


If on the other hand I iterate over the XML like this with readNext():

  while ((tokenType = streamReader.readNext()) != QXmlStreamReader::EndDocument) {
    if (tokenType == QXmlStreamReader::StartElement) {
      qDebug("name: %s", qPrintable(streamReader.name().toString()));
      QXmlStreamAttributes attributes = streamReader.attributes();
      foreach(QXmlStreamAttribute attribute, attributes) {
        qDebug("    Attribute: name: %s, value: %s", qPrintable(attribute.name().toString()), qPrintable(attribute.value().toString()));
      }
    }

I do get all elements as expected.


The only difference between my readNextStartElement() version and the http://doc.trolltech.com/4.7/xml-streambookmarks.html example seems to be that in the later they do a readElementText() and a skipCurrentElement() in between (and this example seems to work for me, at least with a simple *.xbel bookmark file. I have yet to try out a more complex one, e.g. with several "folders" or so). But other than that also this Qt example seems to simply iterate over the entire XML with readNextStartElement().


So what am I doing wrong? Is this supposed to work like I assume, or is this a bug? This is on Qt 4.7.1. Example code and test file attached.

Cheers, Oliver





-- 
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22


-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: main.cpp
Url: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20101221/b5ad5630/attachment.pl 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: QtStreamReaderTest.pro
Type: application/octet-stream
Size: 302 bytes
Desc: QtStreamReaderTest.pro
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20101221/b5ad5630/attachment.obj 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.xml
Type: text/xml
Size: 192 bytes
Desc: test.xml
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20101221/b5ad5630/attachment.xml 


More information about the Qt-interest-old mailing list