XML files has became a very popular file format. This is mainly due to its simplicity and mostly beacuse these files are human and machine readable. This article shows an example of XML file reading with Qt.
Before processing any XML file, Qt must be configured. In the project file (.pro), add the following line to set compiler to use the XML library:
QT += xml
Now add, the required libraries in your source code:
// Library needed for processing XML documents
#include <QtXml>
// Library needed for processing files
#include <QFile>
Let’s consider the following XML file named billofmaterial.xml:
<!-- File billofmaterial.xml-->
<BOM BOARD="Motor controller" YEAR="2014">
<COMPONENT ID="R1">
<NAME>Resistor</NAME>
<VALUE>47000</VALUE>
</COMPONENT>
<COMPONENT ID="C1">
<NAME>Capacitor</NAME>
<VALUE>100e-6</VALUE>
</COMPONENT>
<COMPONENT ID="U1">
<VALUE>0</VALUE>
<NAME>Driver</NAME>
</COMPONENT>
</BOM>
To read an XML file, data must first be loaded in a QFile. Secondly, content must be parsed with setContent:
//The QDomDocument class represents an XML document.
QDomDocument xmlBOM;
// Load xml file as raw data
QFile f("billofmaterial.xml");
if (!f.open(QIODevice::ReadOnly ))
{
// Error while loading file
std::cerr << "Error while loading file" << std::endl;
return 1;
}
// Set data into the QDomDocument before processing
xmlBOM.setContent(&f);
f.close();
Once the file is loaded, the first node (called root) can be read according to the following example:
// Extract the root markup
QDomElement root=xmlBOM.documentElement();
// Get root names and attributes
QString Type=root.tagName();
QString Board=root.attribute("BOARD","No name");
int Year=root.attribute("YEAR","1900").toInt();
// Display root data
std::cout << "Type = " << Type.toStdString().c_str() << std::endl;
std::cout << "Board = " << Board.toStdString().c_str() << std::endl;
std::cout << "Year = " << Year << std::endl;
std::cout << std::endl;
Finally, whole data can be read according to the following example:
// Get the first child of the root (Markup COMPONENT is expected)
QDomElement Component=root.firstChild().toElement();
// Loop while there is a child
while(!Component.isNull())
{
// Check if the child tag name is COMPONENT
if (Component.tagName()=="COMPONENT")
{
// Read and display the component ID
QString ID=Component.attribute("ID","No ID");
// Get the first child of the component
QDomElement Child=Component.firstChild().toElement();
QString Name;
double Value;
// Read each child of the component node
while (!Child.isNull())
{
// Read Name and value
if (Child.tagName()=="NAME") Name=Child.firstChild().toText().data();
if (Child.tagName()=="VALUE") Value=Child.firstChild().toText().data().toDouble();
// Next child
Child = Child.nextSibling().toElement();
}
// Display component data
std::cout << "Component " << ID.toStdString().c_str() << std::endl;
std::cout << " Name = " << Name.toStdString().c_str() << std::endl;
std::cout << " Value = " << Value << std::endl;
std::cout << std::endl;
}
// Next component
Component = Component.nextSibling().toElement();
}
Examples and source code can be downloaded below: