Работа с XML в C++: библиотеки pugixml, TinyXML-2 и RapidXML

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с XML в C++: выбираем библиотеку для парсинга и создания документов

XML (eXtensible Markup Language) остаётся одним из ключевых форматов для хранения и передачи структурированных данных. В C++ отсутствует встроенная поддержка XML (кроме устаревшего MSXML), поэтому разработчики используют сторонние библиотеки. В этой статье мы разберём три наиболее популярные лёгкие библиотеки: pugixml, TinyXML-2 и RapidXML. Все они работают без внешних зависимостей, поддерживают UTF-8 и подходят для embedded-систем.

1. pugixml — универсальный выбор

pugixml — самая быстрая и функциональная библиотека среди «лёгких» решений. Она поддерживает XPath, потоковую обработку и удобный API в стиле STL.

Установка: достаточно скопировать pugixml.hpp и pugixml.cpp в проект.

Пример: парсинг и чтение 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 << "Ошибка: " << result.description() << std::endl;
        return 1;
    }

    // Получаем корневой элемент
    pugi::xml_node root = doc.child("configuration");

    // Обход всех элементов <parameter>
    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;
}

Создание XML-документа

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("Пример");
item.append_child("price").text().set(99.99);

doc.save_file("output.xml");

Особенности:

  • Поддержка XPath 1.0 для сложных запросов.
  • Работа с кодировками UTF-8/16/32.
  • Режим «ленивого» парсинга для больших файлов.

2. TinyXML-2 — простота и надёжность

TinyXML-2 — наследник классической TinyXML, оптимизированный по памяти. Идеален для несложных проектов, где не нужен XPath.

Установка: два файла: tinyxml2.h и tinyxml2.cpp.

Пример: чтение атрибутов

#include "tinyxml2.h"
#include <iostream>

int main() {
    tinyxml2::XMLDocument doc;
    tinyxml2::XMLError err = doc.LoadFile("data.xml");

    if (err != tinyxml2::XML_SUCCESS) {
        std::cerr << "Ошибка загрузки: " << 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 << "Книга: " << title << ", страниц: " << pages << std::endl;
    }

    return 0;
}

Создание 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("Ноутбук");
root->InsertEndChild(product);

doc.SaveFile("catalog.xml");

Плюсы:

  • Минимальное потребление памяти (без копирования строк).
  • Простой и интуитивный API.
  • Поддержка XML комментариев и CDATA.

3. RapidXML — скорость любой ценой

RapidXML — header-only библиотека, ориентированная на максимальную производительность. Парсит XML in-place (изменяя исходную строку), что даёт прирост скорости, но накладывает ограничения.

Установка: достаточно подключить rapidxml.hpp.

Пример: парсинг

Рекомендаций