C++ XML 处理库 PugiXML 使用指南与实战
pugixml 是一款经典且高效的 C++ XML 处理库,非常适合用于学习项目结构或构建高性能应用。以下基于 v1.15 版本整理其核心信息与实战用法。
基础信息
作为高知名度的开源项目,pugixml 拥有超过 330 个公共代码库依赖,在 vcpkg 包管理器中热度排名前 5.4%。它采用宽松的 MIT 许可证,允许在商业项目中自由使用、修改和分发,仅需保留原作者版权声明。
核心优势
- DOM-like 接口:直观遍历与修改 XML 文档树。
- 高性能解析:非验证性解析器速度极快,适合性能敏感场景。
- XPath 支持:内置 XPath 1.0 实现,支持复杂查询。
- Unicode 兼容:完美支持多种编码并自动转换。
广泛应用于 Assimp、Qt 模块及各类游戏引擎中。
环境准备
Windows x64 环境下需包含以下文件:
- 头文件:
pugiconfig.hpp,pugixml.hpp - 库文件:
pugixml.lib
实战代码示例
1. 加载与遍历
从文件加载 XML 并遍历节点是基础操作。注意检查加载结果是否成功。
#include <iostream>
#include "pugixml/pugixml.hpp"
int traverse_base() {
pugi::xml_document doc;
// 替换为实际路径
if (!doc.load_file("xgconsole.xml")) return -1;
pugi::xml_node tools = doc.child("Profile").child("Tools");
for (pugi::xml_node tool = tools.first_child(); tool; tool = tool.next_sibling()) {
std::cout << "Tool:";
for (pugi::xml_attribute attr = tool.first_attribute(); attr; attr = attr.next_attribute()) {
std::cout << " " << attr.name() << "=" << attr.value();
}
std::cout << std::endl;
}
return 0;
}
2. XPath 查询
利用 XPath 可以快速定位特定元素,支持编译后的查询对象以提升性能。
int xpath_query() {
pugi::xml_document doc;
if (!doc.load_file("xgconsole.xml")) return -1;
// 编译查询对象
pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote='true']");
pugi::xpath_node_set tools = query_remote_tools.evaluate_node_set(doc);
if (!tools.empty()) {
std::cout << "Remote tool: ";
tools[0].node().print(std::cout);
}
// 数值计算
pugi::xpath_query query_timeouts("sum(//Tool/@Timeout)");
std::cout << "Total Timeout: " << query_timeouts.evaluate_number(doc) << std::endl;
return 0;
}
3. 文档修改
动态添加节点、属性并保存是常见需求。
int modify_add() {
pugi::xml_document doc;
// 添加新节点
pugi::xml_node node = doc.append_child("node");
// 添加文本子节点
pugi::xml_node descr = node.append_child("description");
descr.append_child(pugi::node_pcdata).set_value("Simple node");
// 添加属性
pugi::xml_node param = node.insert_child_before("param", descr);
param.append_attribute("name") = "version";
param.append_attribute("value") = 1.1;
doc.print(std::cout);
return 0;
}
4. 异常处理
XPath 查询可能抛出异常,建议捕获 pugi::xpath_exception 以避免程序崩溃。
int xpath_error() {
pugi::xml_document doc;
if (!doc.load_file("xgconsole.xml")) return -1;
try {
doc.select_nodes("//nodes[#true()]");
} catch (const pugi::xpath_exception& e) {
std::cout << "Select failed: " << e.what() << std::endl;
}
return 0;
}
总结
pugixml 以其轻量、快速和易用性成为 C++ 领域处理 XML 的首选之一。通过上述示例,你可以掌握从加载、查询到修改的完整流程。在实际集成时,请确保链接对应的库文件,并根据项目需求调整解析选项。
