Seite 1 von 1

[Gelöst] QXmlStreamReader u. spezielles XML File?

Verfasst: 4. April 2011 16:40
von bronko
Hallo,

folgendes Problem:
Ich habe eine XML Datei mit folgendem Eintrag:

Code: Alles auswählen

...
<term>
  Global 
  <ref refid="abcde" kindref="member">myText</ref> 
 (void) 
  </term>
...
Ich habe:

Code: Alles auswählen

xml.readNextStartElement(); // term
qDebug() << xml.readElementText(); //"Global"
xml.readNextStartElement(); // ref
qDebug() << xml.attributes().value("refid").toString(); //abcde
qDebug()  << xml.attributes().value("kindref");//member
qDebug()  << xml.readElementText(); //""
qDebug()  << xml.errorString(); // "Expected character data."
Den Rest der Datei lese ich korrect, wenn es aber zu diesen Zeilen komme, dann sagt xml.errorString() "Expected character data."

Ich kenne mich mit XML nicht gut aus, aber ist es möglich mit QXmlStreamReader das korrekt auszulesen?
Was mache ich falsch?

Bronko

Verfasst: 6. April 2011 08:14
von bronko
Keiner ne Idee? Weiß jemand ob das überhaupt gültiges XML ist?

Verfasst: 6. April 2011 09:03
von franzf
Der Text "myText" ist eine eigene Node -> CDATA. Verwende nur "readNext()" und achte auf den Rückgabetyp (TokenType), zum Debuggen kannst ihn ja einfach ausgeben.

Verfasst: 6. April 2011 09:54
von bronko
Danke franzf,
hab etwas über CDATA gelesen (http://www.w3schools.com/xml/xml_cdata.asp)
Dort steht "The term CDATA is used about text data that should not be parsed by the XML parser. " :?:
Ich will es aber parsen...

Auf jedenfall habe ich das hinzugefügt

Code: Alles auswählen

xml.readNextStartElement(); // term
qDebug() << xml.readElementText(); //"Global"
xml.readNextStartElement(); // ref
qDebug() << xml.attributes().value("refid").toString(); //abcde
qDebug()  << xml.attributes().value("kindref");//member
qDebug() << "next" <<xml.readNext(); // 1 
qDebug()  << xml.readElementText(); //""
qDebug()  << xml.errorString(); // "Expected character data."
Er gibt mir immer QXmlStreamReader::Invalid zurück.
Auch an anderen Stellen. Lt. Doku müsste er abbrechen, macht er aber nicht.
Oder hast du etwas anderes gemeint?

Bronko

Verfasst: 6. April 2011 10:48
von franzf
"Verwende NUR readNext()", war das nicht klar genug? Dann sieht man, in welcher Reihenfolge was wie wann kommt.
Und für sowas schreibt man sich dann ein winziges Test-Programm.

Code: Alles auswählen

#include <QXmlStreamReader>
#include <QDebug>

int main() {
    QXmlStreamReader reader("<term>Global<ref refid='abcde' kindref='member'>myText</ref>(void)</term>");
    while( !reader.atEnd() ) {
        qDebug() << "Token Type:" << reader.readNext();
        qDebug() << "Name: " << reader.name().toString();
        qDebug() << "Text:" << reader.text().toString();
    }
}
Ausgabe:

Code: Alles auswählen

Token Type: 2 
Name:  "" 
Text: "" 
Token Type: 4 
Name:  "term" 
Text: "" 
Token Type: 6 
Name:  "" 
Text: "Global" 
Token Type: 4 
Name:  "ref" 
Text: "" 
Token Type: 6 
Name:  "" 
Text: "myText" 
Token Type: 5 
Name:  "ref" 
Text: "" 
Token Type: 6 
Name:  "" 
Text: "(void)" 
Token Type: 5 
Name:  "term" 
Text: "" 
Token Type: 3 
Name:  "" 
Text: ""
Man könnte jetzt natürlich noch ausbauen mit Iteration über die attributes(), aber das ist ja nicht das Problem.

Verfasst: 6. April 2011 12:32
von bronko
Vielen Dank! Das war ein genereller Denkfehler.

Kann man generell sagen, dass es besser ist readNext() anstatt readNextStartElement() zu verwenden um den tokenType prüfen zu können?

Verfasst: 6. April 2011 12:42
von pfid
bronko hat geschrieben:Vielen Dank! Das war ein genereller Denkfehler.

Kann man generell sagen, dass es besser ist readNext() anstatt readNextStartElement() zu verwenden um den tokenType prüfen zu können?
Die Doku zu den beiden Methoden kennst du?

Verfasst: 6. April 2011 12:43
von franzf
readNext() iteriert halt über ALLE Node-Typen, readNextStartElement() iteriert nur über XML-Elements (Also "<ref attribute="abc">").
Ersetz halt einfach readNext durch readNextStartElement() und schau was passiert. Weck den Spieltrieb in dir! :D