In this section, we will learn how to process data taken from an XML file and extract it using the stream reader.
Let's create a simple program that reads and processes XML files by following these steps:
scene.xml
:<?xml version="1.0" encoding="UTF-8"?> <scene> <object tag="building"> <name>Library</name> <position>120.0,0.0,50.68</position> <rotation>0.0,0.0,0.0</rotation> <scale>1.0,1.0,1.0</scale> </object> <object tag="building"> <name>Town Hall</name> <position>80.2,0.0,20.5</position> <rotation>0.0,0.0,0.0</rotation> <scale>1.0,1.0,1.0</scale> </object> <object tag="prop"> <name>Tree</name> <position>10.46,-0.2,80.2</position> <rotation>0.0,0.0,0.0</rotation> <scale>1.0,1.0,1.0</scale> </object> </scene>
mainwindow.h
. Add the following headers at the top of the script, right after #include <QMainWindow>
:#include <QXmlStreamReader> #include <QDebug> #include <QFile> #include <QFileDialog>
mainwindow.ui
and drag a Push Button from the widget box on the left-hand side to the UI editor. Change the object name of the button to loadXmlButton
and its display text to Load XML:clicked()
option and press the OK button. Qt will now insert a slot function in your header and source files called on_loadXmlButton_clicked()
.on_loadXmlButton_clicked()
function:What we're trying to do in this example is to extract and process data from an XML file using the QXmlStreamReader
class. Imagine you're making a computer game and you're using XML files to store the attributes of all the objects in your game scene. In this case, the XML format plays an important role in storing the data in a structured way, which allows for easy extraction.
To begin with, we need to add the header of the class related to XML to our source file, which in this case is the QXmlStreamReader
class. QXmlStreamReader
is built into Qt's core library, so there is no need to include any additional modules with it, which also means that it's the recommended class to use for processing XML data in Qt.
Once we clicked on the Load XML button, the on_loadXmlButton_clicked()
slot will be called; this is where we write the code for processing the XML data.
First, we use a file dialog for selecting the XML file we want to process. Then, send the selected file's filename, together with its path, to the QFile
class to open and read the text data of the XML file. After that, the file's data is sent to the QXmlStreamReader
class for processing.
We use a while-loop to read through the entire XML file and check every element processed by the stream reader. We determine whether the element is a start element or an end element. If it's a start element, we will then check the name of the element to determine whether the element should contain any data that we need.
Then, we will extract the data, either in the form of an attribute or text. An element may have more than one attribute, which is why we must loop through all the attributes and extract them one by one.
Besides the web browser, many commercial game engines and interactive applications also use the XML format to store information for in-game scenes, meshes, and other forms of asset used in their product. This is because the XML format provides many benefits over other file formats, such as a compact file size, high flexibility and extendibility, easy file recovery, and a relational tree structure that allows it to be used for highly efficient and performance-critical applications such as search engines, intelligent data mining servers, scientific simulations, and so on.
Let's learn a little bit about the format of an XML file. We will use scene.xml
, which we used in the previous example and looks like this:
<?xml version="1.0" encoding="UTF-8"?> <scene> <object tag="building"> <name>Library</name> <position>120.0,0.0,50.68</position> <rotation>0.0,0.0,0.0</rotation> <scale>1.0,1.0,1.0</scale> </object> <object tag="building"> <name>Town Hall</name> <position>80.2,0.0,20.5</position> <rotation>0.0,0.0,0.0</rotation> <scale>1.0,1.0,1.0</scale> </object> <object tag="prop"> <name>Tree</name> <position>10.46,-0.2,80.2</position> <rotation>0.0,0.0,0.0</rotation> <scale>1.0,1.0,1.0</scale> </object> </scene>
In XML, a tag is a line of markup text that starts with a <
symbol and ends with a >
symbol. For example, <scene>
is a tag called scene
, <object>
is a tag called object
and so on. Tags come in three flavors:
<scene>
</scene>
<scene />
Whenever you write a start tag, it must end with an end tag, otherwise your XML data will be invalid. An empty-element tag, however, is a standalone tag and does not need an end tag behind it.
At the top of scene.xml
, you will see a tag called xml
which stores the version of the XML format and the encoding type, which in this case is XML version 1.0 and UTF-8 (8-bit Unicode) encoding. This line is called XML declaration and it must exist in any of your XML files to validate its format.
After that, you will see tags that have attributes stored in them, for example <object tag="building">
. This means that the object
tag contains an attribute called tag
, which contains a value, building
. You can put as many attributes as you like in a tag, for example <object tag="building" color="red" name="LA Community Hospital" coordinate="34.0191757,-118.2567239">
. Each of these attributes stores distinctive data that can be retrieved easily using Qt.
Other than that, you can also store data between the start tag and the end tag, for example <name>Town Hall</name>
. This method, however, is not relevant to the empty-element tag, since it is a standalone tag and isn't followed by a close tag. Therefore, you can only store attributes in an empty-element tag.
To learn more about the XML format, visit http://www.w3schools.com/xml.
18.119.235.79