Working with XML in C++: choosing a library for parsing and creating documents
XML (eXtensible Markup Language) remains one of the key formats for storing and transmitting structured data. C++ lacks built-in XML support (except for the outdated MSXML), so developers use third-party libraries. In this article, we will cover three of the most popular lightweight libraries: pugixml, TinyXML-2 and RapidXML. All of them work without external dependencies, support UTF-8 and are suitable for embedded systems.
1. pugixml — a universal choice
pugixml is the fastest and most feature-rich library among "lightweight" solutions. It supports XPath, streaming processing and a convenient STL-style API.
Installation: simply copy pugixml.hpp and pugixml.cpp into your project.
Example: parsing and reading XML
#include "pugixml.hpp"#include <iostream>
int main() { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file("config.xml");
if (!result) { std::cerr << "Error: " << result.description() << std::endl; return 1; }
// Get the root element pugi::xml_node root = doc.child("configuration");
// Iterate over all <parameter> elements for (pugi::xml_node param : root.children("parameter")) { std::string name = param.attribute("name").value(); std::string value = param.child_value("value"); std::cout << name << " = " << value << std::endl; }
return 0;}Creating an XML document
pugi::xml_document doc;pugi::xml_node root = doc.append_child("root");root.append_attribute("version") = "1.0";
pugi::xml_node item = root.append_child("item");item.append_attribute("id") = 1;item.append_child("name").text().set("Example");item.append_child("price").text().set(99.99);
doc.save_file("output.xml");Features:
- XPath 1.0 support for complex queries.
- UTF-8/16/32 encoding support.
- "Lazy" parsing mode for large files.
2. TinyXML-2 — simplicity and reliability
TinyXML-2 is the successor to the classic TinyXML, optimized for memory usage. It is ideal for simple projects where XPath is not needed.
Installation: two files: tinyxml2.h and tinyxml2.cpp.
Example: reading attributes
#include "tinyxml2.h"#include <iostream>
int main() { tinyxml2::XMLDocument doc; tinyxml2::XMLError err = doc.LoadFile("data.xml");
if (err != tinyxml2::XML_SUCCESS) { std::cerr << "Load error: " << doc.ErrorStr() << std::endl; return 1; }
tinyxml2::XMLElement* element = doc.FirstChildElement("book"); if (element) { const char* title = element->Attribute("title"); int pages = element->IntAttribute("pages"); std::cout << "Book: " << title << ", pages: " << pages << std::endl; }
return 0;}Creating XML
tinyxml2::XMLDocument doc;tinyxml2::XMLDeclaration* decl = doc.NewDeclaration();doc.InsertFirstChild(decl);
tinyxml2::XMLElement* root = doc.NewElement("catalog");doc.InsertEndChild(root);
tinyxml2::XMLElement* product = doc.NewElement("product");product->SetAttribute("id", 101);product->SetText("Laptop");root->InsertEndChild(product);
doc.SaveFile("catalog.xml");Advantages:
- Minimal memory consumption (no string copying).
- Simple and intuitive API.
- Support for XML comments and CDATA.