C++ is one of the most powerful programming languages, making its presence felt in every corner of the development world. Since its inception in 1985, C++ has been the go-to language for learners, engineers, scientists, and researchers alike.
Picture this: You have an application written in C++ that needs to save and access data from an XML file. What do you do? Well, you’ve got a couple of choices. You could become your own XML parsing mastermind, which is quite a challenge if you have the time and skillset. Alternatively, you could take a shortcut and employ an XML parser like TinyXML2, diving into its inner workings without a sweat.
In this tutorial, you will learn how to Read and Write to an XML file using C++ and TinyXML2, an XML parser developed by Lee Thomason.
First, download the TinyXML library by clicking on the following link:
https://github.com/leethomason/tinyxml2
Afterward, it is necessary to incorporate the library into your project, which varies based on your IDE. Detailed instructions for this process can be found by visiting the link below:
https://github.com/leethomason/tinyxml2/blob/master/readme.md
For the sake of this tutorial, let’s create an XML file for employees’ records. Below is the structure of the file that we will be using in this tutorial:
<data> <Employees> <Employee> <Name>Mike</Name> <Department>Engineering</Department> <Positing>Engineer</Positing> <Salary>5000</Salary> <HireData>01/01/2021</HireData> </Employee> <Employee> <Name>Fred</Name> <Department>Human Resource</Department> <Positing>Administration Assistant</Positing> <Salary>3000</Salary> <HireData>01/01/2016</HireData> </Employee> <Employee> <Name>Nancy</Name> <Department>Information Technology</Department> <Positing>Programmer</Positing> <Salary>4000</Salary> <HireData>01/01/2014</HireData> </Employee> </Employees> </data>
The file above contains information about employees. It features details about three staff members, each enclosed within a <Employee>
tag, and the entire collection of employees is enclosed within a <Employees>
(with s) tag.
The first operation in this tutorial is reading an XML file. The code below reads the data from the XML file, formats it, then prints it to the console.
#include <iostream> #include <tinyxml2.h> #include <iomanip> using namespace std; using namespace tinyxml2; int main() { XMLDocument doc; const char * path = "\\bin\\Debug\\data.xml"; char salaryText[20]; // Load XML data doc.LoadFile(path); // Get the root Element from the XMLDocument instance XMLElement * pRootElement = doc.RootElement(); // Print the Header cout << '|' << setw(6) << "Name" << '|' << setw(14) << "Department" << '|' << setw(12) << "Position" << '|' << setw(8) << "Salary" << '|' << setw(12) << "Hire Date" << endl; cout << "----------------------------------------------------------"; cout << endl; if (pRootElement != NULL) { //Get 'Employees' Node XMLElement * pEmployees = pRootElement -> FirstChildElement("Employees"); if (NULL != pEmployees) { //Get 'Account' Node XMLElement * pEmployee = pEmployees -> FirstChildElement("Employee"); while (pEmployee) { // Get 'Name' Node XMLElement * pName = pEmployee -> FirstChildElement("Name"); if (pName != NULL) { //Print 'Name' cout << '|' << setw(6) << pName -> GetText(); } //Get 'Department' Node XMLElement * pDepartment = pEmployee -> FirstChildElement("Department"); if (pDepartment != NULL) { // Print 'Department' cout << '|' << setw(14) << pDepartment -> GetText(); } // Get 'Position' Node XMLElement * pPosition = pEmployee -> FirstChildElement("Position"); if (pPosition != NULL) { //Print 'Position' cout << '|' << setw(12) << pPosition -> GetText(); } // Get 'Salary' Node XMLElement * pSalary = pEmployee -> FirstChildElement("Salary"); if (pSalary != NULL) { // Convert the double value to *char strcpy(salaryText, "$"); strcat(salaryText, pSalary -> GetText()); //Print 'Salary' cout << '|' << setw(8) << salaryText << '|'; } XMLElement * openDate = pEmployee -> FirstChildElement(strdup("HireData")); if (openDate != NULL) { //Print the openDate Node cout << setw(12) << openDate -> GetText() << '|'; } cout << endl; // Next Employee pEmployee = pEmployee -> NextSiblingElement("Employee"); } cout << "\n"; } } return 0; }
Run your program, you should get the following output:
| Name| Department| Position| Salary| Hire Date ---------------------------------------------------------- | Mike| Engineering| Engineer| $5000| 01/01/2021| | Fred| HR| Assistant| $3000| 01/01/2016| | Nancy| IT| Programmer| $4000| 01/01/2014| Process returned 0 (0x0) execution time : 1.118 s Press any key to continue.
Are you ready to bring a fresh new employee on board? Great! Let’s utilize the insert operation by implementing the InsertEndChild
function from the TinyXML2 library:
void InsertEmployee() { XMLDocument doc; const char * path = "\\bin\\Debug\\data.xml"; // Define new employee Data char name[100] = "Mark"; char department[100] = "IT"; char position[20] = "QA"; char salary[10] = "3000"; char hireDate[20] = "05/12/2023"; // Load XML data doc.LoadFile(path); //Get root Element XMLElement * root = doc.RootElement(); // Get 'Employees' Child XMLElement * Employees = root -> FirstChildElement("Employees"); //Create new Employee XMLNode * pRoot = doc.NewElement("Employee"); //Insert new Element Employees -> InsertEndChild(root); //Create 'Name' Element XMLElement * pElement = doc.NewElement("Name"); // Set new Element Value pElement -> SetText(name); // Insert new Element pRoot -> InsertEndChild(pElement); //Create 'Department' Element pElement = doc.NewElement("Department"); // Set new Element Value pElement -> SetText(department); // Insert new Element pRoot -> InsertEndChild(pElement); //Create 'Position' Element pElement = doc.NewElement("Position"); // Set new Element Value pElement -> SetText(position); // Insert new Element pRoot -> InsertEndChild(pElement); //Create 'Salary' Element pElement = doc.NewElement("Salary"); // Set new Element Value pElement -> SetText(salary); // Insert new Element pRoot -> InsertEndChild(pElement); //Create 'HireDate' Element pElement = doc.NewElement("HireDate"); // Set new Element Value pElement -> SetText(hireDate); //Insert new Element pRoot -> InsertEndChild(pElement); //Apply the changes to the XML file doc.SaveFile(path); }
Run the function, the output for the new XML data file is as the following:
| Name| Department| Position| Salary| Hire Date ---------------------------------------------------------- | Mike| Engineering| Engineer| $5000| 01/01/2021| | Fred| HR| Assistant| $3000| 01/01/2016| | Nancy| IT| Programmer| $4000| 01/01/2014| | Mark| IT| QA| $3000| 05/12/2023| Process returned 0 (0x0) execution time : 0.557 s Press any key to continue.
of course, you have the option to modify this function by incorporating parameters, enabling you to call it and pass your specific parameters.
Happy Coding!