| ID | Creation date | June 8, 2009 | |
| Platform | Qt | Tested on devices | 5800 XpressMusic |
| Category | Qt for Symbian | Subcategory |
| Keywords (APIs, classes, methods, functions): Qt, XML, SAX, QXmlStreamReader |
This example shows you how you parse XML with QXmlStreamReader. The QXmlStreamReader class provides a fast parser for reading well-formed XML via a simple streaming API.
This snippet can be self-signed. As it does not use any API which require developer/certified signing.
<?xml version="1.0" encoding="UTF-8" ?>
<persons>
<person>
<firstname>John</firstname>
<surname>Doe</surname>
<email>john.doe@example.com</email>
<website>http://en.wikipedia.org/wiki/John_Doe</website>
</person>
<person>
<firstname>Jane</firstname>
<surname>Doe</surname>
<email>jane.doe@example.com</email>
<website>http://en.wikipedia.org/wiki/John_Doe</website>
</person>
<person>
<firstname>Matti</firstname>
<surname>Meikäläinen</surname>
<email>matti.meikalainen@example.com</email>
<website>http://fi.wikipedia.org/wiki/Matti_Meikäläinen</website>
</person>
</persons>
#include <QtXml/QXmlStreamReader>
class QXSRExample : public QMainWindow {
Q_OBJECT
public:
QXSRExample(QWidget *parent = 0);
~QXSRExample();
private slots:
void parseXML();
private:
QPointer<QVBoxLayout> _layout;
void setupUI();
QMap<QString, QString> parsePerson(QXmlStreamReader& xml);
void addElementDataToMap(QXmlStreamReader& xml,
QMap<QString, QString>& map) const;
void addPersonsToUI(QList< QMap<QString,QString> >& persons);
};
void QXSRExample::parseXML() {
/* We'll parse the example.xml */
QFile* file = new QFile(":/example.xml");
/* If we can't open it, let's show an error message. */
if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
QMessageBox::critical(this,
"QXSRExample::parseXML",
"Couldn't open example.xml",
QMessageBox::Ok);
return;
}
/* QXmlStreamReader takes any QIODevice. */
QXmlStreamReader xml(file);
QList< QMap<QString,QString> > persons;
/* We'll parse the XML until we reach end of it.*/
while(!xml.atEnd() &&
!xml.hasError()) {
/* Read next element.*/
QXmlStreamReader::TokenType token = xml.readNext();
/* If token is just StartDocument, we'll go to next.*/
if(token == QXmlStreamReader::StartDocument) {
continue;
}
/* If token is StartElement, we'll see if we can read it.*/
if(token == QXmlStreamReader::StartElement) {
/* If it's named persons, we'll go to the next.*/
if(xml.name() == "persons") {
continue;
}
/* If it's named person, we'll dig the information from there.*/
if(xml.name() == "person") {
persons.append(this->parsePerson(xml));
}
}
}
/* Error handling. */
if(xml.hasError()) {
QMessageBox::critical(this,
"QXSRExample::parseXML",
xml.errorString(),
QMessageBox::Ok);
}
xml.clear();
this->addPersonsToUI(persons);
}
QMap<QString, QString> QXSRExample::parsePerson(QXmlStreamReader& xml) {
QMap<QString, QString> person;
/* Let's check that we're really getting a person. */
if(xml.tokenType() != QXmlStreamReader::StartElement &&
xml.name() == "person") {
return person;
}
/* Next element... */
xml.readNext();
/*
* We're going to loop over the things because the order might change.
* We'll continue the loop until we hit an EndElement named person.
*/
while(!(xml.tokenType() == QXmlStreamReader::EndElement &&
xml.name() == "person")) {
if(xml.tokenType() == QXmlStreamReader::StartElement) {
/* We've found first name. */
if(xml.name() == "firstname") {
this->addElementDataToMap(xml, person);
}
/* We've found surname. */
if(xml.name() == "surname") {
this->addElementDataToMap(xml, person);
}
/* We've found email. */
if(xml.name() == "email") {
this->addElementDataToMap(xml, person);
}
/* We've found website. */
if(xml.name() == "website") {
this->addElementDataToMap(xml, person);
}
}
/* ...and next... */
xml.readNext();
}
return person;
}
void QXSRExample::addElementDataToMap(QXmlStreamReader& xml,
QMap<QString, QString>& map) const {
/* We need a start element, like <foo> */
if(xml.tokenType() != QXmlStreamReader::StartElement) {
return;
}
/* Let's read the name... */
QString elementName = xml.name().toString();
/* ...go to the next. */
xml.readNext();
/*
* This elements needs to contain Characters so we know it's
* actually data, if it's not we'll leave.
*/
if(xml.tokenType() != QXmlStreamReader::Characters) {
return;
}
/* Now we can add it to the map.*/
map.insert(elementName, xml.text().toString());
}
void QXSRExample::addPersonsToUI(QList< QMap<QString,QString> >& persons) {
while(!persons.isEmpty()) {
QGroupBox* personGB = new QGroupBox("Person");
QFormLayout* layout = new QFormLayout;
QMap<QString,QString> person = persons.takeFirst();
layout->addRow("First name", new QLineEdit(person["firstname"]));
layout->addRow("Surname", new QLineEdit(person["surname"]));
layout->addRow("E-mail", new QLineEdit(person["email"]));
layout->addRow("Website", new QLineEdit(person["website"]));
personGB->setLayout(layout);
this->_layout->addWidget(personGB);
}
}
You've been able to parse the XML and display it in the UI.
<?xml version="1.0" encoding="UTF-8" ?>
<persons>
<person firstname="abc" surname="def" number="1234" />
<person firstname="ghi" surname="jkl" number="51234" />
<person firstname="mno" surname="pqr" number="61234" />
<person firstname="stv" surname="wxy" number="81234" />
<person firstname="zab" surname="cde" number="61234" />
</persons>
#include <QtXml/QXmlStreamReader>
class ContactDatabse
{
public:
ContactDatabse(QString firstName, QString surName, QString phoneNumber);
~ContactDatabse();
QString getFirstName();
QString getSurName();
QString getPhoneNumber();
private:
QString firstName;
QString surName;
QString phoneNumber;
};
class QXSRExample : public QMainWindow {
Q_OBJECT
public:
QXSRExample(QWidget *parent = 0);
~QXSRExample();
private slots:
void parseXML();
private:
QPointer<QVBoxLayout> _layout;
void setupUI();
void addPersonsToUI();
void parsePerson(QXmlStreamReader& reader);
QList<ContactDatabse> database;
};
/* The implementaion of parseXML() is same as explained in above example, so ommitted from here */
void QXSRExample::parsePerson(QXmlStreamReader& xml)
{
/* parse each tag and add data to list
*We'll continue the loop until we hit an EndElement named persons
*/
while (!xml.atEnd())
{
/* check whether it is starting of tag <person> , if yes then parse it
*/
if (xml.isStartElement() && xml.name() == "person")
{
/* get all attributes and its value of a tag in attrs variable.
*/
QXmlStreamAttributes attrs = xml.attributes();
/*get value of each attribute from QXmlStreamAttributes */
QStringRef fName = attrs.value("firstname");
QStringRef sName = attrs.value("surname");
QStringRef pNumber = attrs.value("number");
if (fName.isEmpty())
{
xml.readNext();
continue;
}
/*create database of one person*/
ContactDatabse data(fName.toString(),sName.toString(),pNumber.toString());
/*add database to list*/
database.append(data);
}
else if(xml.isEndElement() && xml.name() == "persons")
{
/*if EndElement is persons then stop the loop and create UI */
addPersonsToUI();
return;
}
xml.readNext();
}
}
void QXSRExample::addPersonsToUI()
{
/* add all contact data to UI */
while(!database.isEmpty())
{
QGroupBox* personGB = new QGroupBox("Person");
QFormLayout* layout = new QFormLayout;
ContactDatabse person = database.takeFirst();
layout->addRow("First name", new QLineEdit(person.getFirstName()));
layout->addRow("Surname", new QLineEdit(person.getSurName()));
layout->addRow("Phone Number", new QLineEdit(person.getPhoneNumber()));
personGB->setLayout(layout);
this->_layout->addWidget(personGB);
}
}
You've been able to parse the XML and display it in the UI.
No related wiki articles found