PDA

View Full Version : parse xml



rmagro
2nd July 2009, 09:06
is there a generic way to parse all the node of a xml document, and print out the element name its attributes (name="value") and its values ?
For generic way I mean something that not require me to loop many time based on annidation lavel, since in this case it means I have to know the xml specific annidation level..

Thank you
roby

wysota
2nd July 2009, 09:48
You can write a recursive parser using QXmlStreamReader or QDomDocument. You can start with this:

void displayElement(const QDomElement &elem, int indent = 0){
QString out = QString(indent, ' ')+elem.name()+" ";
out += /* parse attributes here */
qDebug() << out;
for(QDomElement subElem = elem.firstChildElement(); !elem.isNull(); subElem = subElem.nextSiblingElement()){
displayElement(subElem, indent+4);
}
}

QDomDocument doc;
doc.setContent(...);
displayElement(doc.documentElement());

smeck
2nd July 2009, 23:27
This is the QXmlStreamReader version. This example will create an output like the following:

-----start----
[ElementName]
[Attribute = Value, ...]
[ElementText if existing]
-----end-----

The bool flag is necessary since reader.readElementText() raises an error if there is no element text. The stream reader version should have very good performance.



QFile sourceFile("source.xml");
if( !sourceFile.open( QIODevice::ReadOnly ) )
return;

QFile targetFile("output.txt");
if( !targetFile.open( QIODevice::WriteOnly ) )
return;

QXmlStreamReader reader(&sourceFile);

QTextStream writer(&targetFile);


bool lastElementHadText = true;
while( !reader.atEnd() ) {

reader.readNext();

if( reader.isStartElement() ) {
if( !lastElementHadText )
writer << "-----end-----" <<endl;

writer << "-----start-----" << endl;
writer << reader.name().toString() << endl;
foreach( QXmlStreamAttribute attribute, reader.attributes() ) {
writer << attribute.name().toString() << "=" << attribute.value().toString() << ", ";
}
if( reader.attributes().count() > 0 )
writer << endl;
}

if( reader.isCharacters() && !reader.isWhitespace() ) {
lastElementHadText = true;
writer << reader.text().toString() << endl;
writer << "-----end-----" <<endl;
}

}

writer.flush();
targetFile.close();
sourceFile.close();



greetings