pugiXML:一个轻量级、高性能的 C++ XML 解析库

发布于:2025-07-20 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

1.简介

2.认识pugiXML库

2.1.下载pugiXML

2.2.使用pugiXML的前提

3.基本使用示例

4.应用场景

5.实际案例

6.总结


1.简介

        PugiXML 是一个轻量级、高性能的 C++ XML 解析库,设计用于快速处理 XML 文档。它是由Arseny Kapoulkine 开发,它以速度快、内存占用小、跨平台支持、API简洁而闻名非常适合嵌入式系统、游戏开发或需要高效 XML 处理的项目。

        核心特点:

1.高性能:解析速度快,内存占用低,适合处理大型 XML 文件。

  • 解析速度快(零拷贝解析、SIMD加速、延迟解析),内存占用低(连续内存块存储节点、内存池),比DOM解析器(如TinyXML)更高效。

  • 支持SAX风格解析(事件驱动(无需将整个文档加载到内存,而是逐行扫描并触发事件回调)),适合大文件处理。

2.简单 API:提供类似 jQuery 的节点选择器(如 XPath-like 表达式)。

3.跨平台:支持 Windows、Linux、macOS、iOS、Android 等。

4.单文件实现:仅需pugixml.hpppugixml.cpp两个文件。

5.完整功能:

  • XML 解析(支持 SAX 和 DOM 模式)。
  • XML 文档创建与修改。
  • XPath 查询支持(有限但实用)。
  • 错误处理与调试信息。

6.内存管理灵活:默认使用标准库(STL),但可禁用STL(PUGIXML_NO_STL) 以适应嵌入式环境(STL容器通常包括动态内存分配和额外的元数据,这些会增加内存占用。嵌入式环境内存有限通常是及KB~几MB。STL依赖标准库导致的环境的依赖性问题)。

7.无依赖: 不依赖第三方库(如 Boost、Qt),仅依赖C++标准库。

8.开源许可:MIT 许可证,可自由用于商业项目。

2.认识pugiXML库

2.1.下载pugiXML

下载地址:https://github.com/zeux/pugixml

源码包含3个文件:

2.2.使用pugiXML的前提

1.语言与编译器的支持

  • C++版本:需要支持C++11或更改标准的编译器(如GCC 4.8+、Clang 3.3+、MSVC 2013+)

2.必要的头文件包含

需包含PugiXML的核心头文件:

#include "pugixml.hpp" //主功能头文件

若需使用XPath查询,需包含:

#include "pugixml.hpp"  
#include "pugixml.cpp" //仅在一个源文件中包含,用于链接XPath实现

3.编译与链接配置

Header-Only模式:

g++ -std=c++11 your_file.cpp -o your_program

XPath支持:

g++ -std=c++11 your_file.cpp path/to/pugixml/src/pugixml.cpp -o your_program

使用CMake集成:

# CMakeLists.txt
add_executable(your_program your_file.cpp)
target_include_directories(your_program PRIVATE path/to/pugixml/src)c)

4.可选配置

禁用STL(嵌入式环境)

#define PUGIXML_NO_STL  // 禁用STL依赖
#include "pugixml.hpp"

禁用异常处理

#define PUGIXML_NO_EXCEPTIONS  // 禁用异常
#include "pugixml.hpp"

禁用 XPath

#define PUGIXML_NO_XPATH  // 禁用XPath支持(减少代码体积)
#include "pugixml.hpp"

5.内存管理注意事项

  • 默认行为:使用标准库的内存分配器

  • 嵌入式优化:通过PUGIXML_MEMORY_POOL宏配置内存池大小

#define PUGIXML_MEMOTY_POOL 16384 //设置16KB内存池
#include "pugixml.hpp"

6.错误处理

错误解析:通过 xml_parse_result 检查解析状态;

pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_string("<root>...</root>");
 
if (!result)
{
    std::cerr << "解析错误:" << result.description() << std::endl;
}

7.使用 PugiXML 最低要求

  • 支持C++ 11的编译器
  • 包含 pugixml.hpp 头文件

对于高级功能(如XPath)或特殊环境(如嵌入式系统),需额外配置宏定义或链接选项。

3.基本使用示例

1.解析 XML 文档

#include "pugixml.hpp"
#include <iostream>

int main() {
    pugi::xml_document doc;
    
    // 从文件加载XML
    if (!doc.load_file("config.xml")) {
        std::cerr << "无法加载XML文件" << std::endl;
        return 1;
    }
    
    // 遍历节点
    for (pugi::xml_node tool: doc.child("tools").children("tool")) {
        std::cout << "工具: " << tool.attribute("name").value() << std::endl;
        
        // 访问子节点
        for (pugi::xml_node feature: tool.children("feature")) {
            std::cout << "  特性: " << feature.child_value() << std::endl;
        }
    }
    
    return 0;
}

2.创建 XML 文档

#include "pugixml.hpp"
#include <iostream>

int main() {
    pugi::xml_document doc;
    
    // 创建根节点
    pugi::xml_node root = doc.append_child("config");
    
    // 添加子节点和属性
    pugi::xml_node network = root.append_child("network");
    network.append_attribute("enabled") = true;
    network.append_child("ip").text() = "192.168.1.1";
    network.append_child("port").text() = 8080;
    
    // 添加注释
    root.prepend_child(pugi::node_comment).set_value("自动生成的配置文件");
    
    // 保存到文件
    doc.save_file("config.xml", "  ");  // 使用2个空格缩进
    
    std::cout << "XML文件已生成" << std::endl;
    return 0;
}

3.使用 XPath 查询

#include "pugixml.hpp"
#include <iostream>

int main() {
    pugi::xml_document doc;
    if (!doc.load_file("config.xml")) return 1;
    
    // 使用XPath查询
    pugi::xpath_node_set nodes = doc.select_nodes("//network/port");
    
    for (pugi::xpath_node node: nodes) {
        std::cout << "端口: " << node.node().text().as_int() << std::endl;
    }
    
    // 查询带属性的节点
    pugi::xpath_node tool = doc.select_node("//tool[@name='editor']");
    if (tool) {
        std::cout << "找到编辑器工具" << std::endl;
    }
    
    return 0;
}

4.使用内存映射文件

pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_buffer_inplace(buffer, size);

4.应用场景

  • 配置文件解析:读取应用程序配置(如游戏配置、服务器设置)。
  • 数据交换:处理 REST API 返回的 XML 数据。
  • 嵌入式系统:在资源受限的设备上解析 XML。
  • 游戏开发:加载游戏关卡数据、角色配置等。
  • 需要高效 XML 处理的场景:替代复杂的 libxml2 或 xerces。

5.实际案例

minidocx: 一个轻量级的跨平台的C++操作word的开源库-CSDN博客

minidocx库就使用了pugixml

通过CMake引入pugixml,CMakeList.txt如下:

cmake_minimum_required(VERSION 3.28)
project(minidocx-next VERSION 1.0.0 LANGUAGES C CXX)

option(BUILD_EXAMPLES  "Build examples"               ON)
option(BUILD_TESTS     "Build tests"                  OFF)
option(WITH_STATIC_CRT "Use static C Runtime library" OFF)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_DEBUG_POSTFIX d)
set(CMAKE_CONFIGURATION_TYPES Debug Release)
set(CMAKE_VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")

set(THIRD_PARTY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty" CACHE PATH "third-party")
set(MINIZ_DIR "${THIRD_PARTY_DIR}/miniz-3.0.2" CACHE PATH "miniz")
set(PUGIXML_DIR "${THIRD_PARTY_DIR}/pugixml-1.13" CACHE PATH "pugixml")

add_library(miniz INTERFACE)
set_target_properties(miniz PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${MINIZ_DIR}"
)

add_library(pugixml INTERFACE)
set_target_properties(pugixml PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${PUGIXML_DIR}"
  INTERFACE_SOURCES             "${PUGIXML_DIR}/pugixml.cpp"
)

include(cmake/util.cmake)

add_library(minidocx STATIC)
aux_inc_directory(include headers)
aux_src_directory(src sources)
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/include/minidocx" PREFIX "Header Files" FILES ${headers})
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/src" PREFIX "Source Files" FILES ${sources})
target_sources(minidocx PRIVATE ${headers} ${sources})
target_include_directories(minidocx PRIVATE include/minidocx)
target_include_directories(minidocx INTERFACE include)
target_compile_definitions(minidocx PRIVATE NAMESPACE=md)
target_link_libraries(minidocx PRIVATE miniz pugixml)
if(WITH_STATIC_CRT)
  set_target_properties(minidocx PROPERTIES MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)
endif()

if(BUILD_EXAMPLES)
  add_subdirectory(examples)
  set_directory_properties(PROPERTIES VS_STARTUP_PROJECT myapp)
endif()

6.总结

优缺点总结

优点 缺点
高性能,解析速度快 XPath 支持有限(不支持完整标准)
单文件实现,无依赖 不支持 XML 命名空间(Namespace)
简洁的 API,易于学习 高级功能(如 XSLT)需自行扩展
跨平台支持
良好的错误处理

相关资源

  • 官方仓库https://github.com/zeux/pugixml
  • 文档:仓库中的readme.mddocs/目录提供详细 API 文档。
  • 性能对比:官方文档包含与其他 XML 库的性能对比。

如果你的项目需要高效、轻量级的 XML 处理,PugiXML 是理想选择。对于需要完整 XPath 支持或复杂 XML 标准的场景,可能需要考虑 libxml2 等更全面的库。


网站公告

今日签到

点亮在社区的每一天
去签到