[Qt-interest] QXmlStreamReader: Usage of readNextStartElement()?
Constantin Makshin
cmakshin at gmail.com
Tue Dec 21 21:14:50 CET 2010
This works:
QXmlStreamReader streamReader(&file);
while (streamReader.readNextStartElement()) {
printf("name: %s\n", qPrintable(streamReader.name().toString()));
QXmlStreamAttributes attributes = streamReader.attributes();
foreach(QXmlStreamAttribute attribute, attributes) {
printf(" Attribute: name: %s, value: %s\n",
qPrintable(attribute.name().toString()),
qPrintable(attribute.value().toString()));
}
// !!!
if (streamReader.name() != "foo")
streamReader.readElementText();
// !!!
}
The problem in your version is that when QXmlStreamReader encounters
the "bar" element and reads its attributes, the current token is still
QXmlStreamReader::StartElement and the next call to the
readNextStartElement() tries to recurse into it, i.e. read child
elements of the "bar" one. But since the "bar" element doesn't have
any "subelements", the next token readNextStartElement() finds is
QXmlStreamReader::EndElement, so the function returns "false" and your
loop ends.
readElementText(), on the other hand, reads element's text, so the
token after if returns is QXmlStreamReader::EndElement. Then
readNextStartElement() gets the next token, which is
QXmlStreamReader::StartElement and therefore everything works as
expected.
On Tue, Dec 21, 2010 at 8:06 PM, <Oliver.Knoll at comit.ch> wrote:
> 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
>
>
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt-interest
>
>
More information about the Qt-interest-old
mailing list