https://github.com/huanhuan0812/litexml
an xml patser library
https://github.com/huanhuan0812/litexml
cpp xml xml-parser
Last synced: 2 days ago
JSON representation
an xml patser library
- Host: GitHub
- URL: https://github.com/huanhuan0812/litexml
- Owner: huanhuan0812
- License: mit
- Created: 2026-07-13T11:49:26.000Z (7 days ago)
- Default Branch: main
- Last Pushed: 2026-07-14T01:09:36.000Z (6 days ago)
- Last Synced: 2026-07-14T03:05:27.506Z (6 days ago)
- Topics: cpp, xml, xml-parser
- Language: C++
- Homepage: https://huanhuan0812.github.io/api-docs/zh/api/LiteXML/api.html
- Size: 60.5 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# LiteXML - 轻量级高性能 XML 解析器
## 项目概述
LiteXML 是一个现代化的 C++ XML 解析库,采用 C++23 标准开发,专注于提供高性能、低内存占用的 XML 解析能力。该库实现了完整的 **DOM 解析器**,同时提供了 **流式(SAX 风格)解析器**,支持命名空间、实体解码、CDATA 段、多编码自动检测等标准 XML 特性。
无论是需要完整 DOM 树的小型配置,还是需要处理 GB 级大型 XML 文件的批量导入场景,LiteXML 均能提供稳定、高效、内存可控的解析能力。
---
## 核心设计理念
### 1. 零拷贝设计
LiteXML 采用 `std::string_view` 作为字符串表示方式,避免了大量字符串拷贝操作。所有文本数据直接引用原始 XML 输入,仅在必要时(如实体解码)才进行内存分配。
流式解析器同样遵循零拷贝原则,事件中返回的 `string_view` 直接引用内部缓冲区。
### 2. 内存池分配器(DOM 模式)
DOM 模式下实现了自定义的 Arena Allocator,所有 DOM 节点和字符串数据都在内存池中分配:
- 减少内存碎片
- 提高分配速度
- 实现批量释放
- 降低内存开销
### 3. 高效的文本处理
- **智能实体解码**:仅在检测到实体引用时才执行解码操作
- **懒加载文本累加**:使用 `TextAccumulator` 高效合并连续文本节点
- **空白处理优化**:可配置的空白字符保留/忽略策略
### 4. 命名空间支持
完整的 XML 命名空间解析和继承机制:
- 支持前缀命名空间声明(`xmlns:prefix`)
- 支持默认命名空间(`xmlns`)
- 自动继承父级命名空间
- 命名空间 URI 解析和存储
- **命名空间解析额外开销 < 1.5%**
---
## 两种解析模式
| 特性 | DOM 解析器 | 流式解析器(SAX 风格) |
|------|-----------|----------------------|
| 内存占用 | 随文档大小线性增长 | 恒定(通常 < 1 MB) |
| 解析速度 | 极快(400+ MB/s) | 高效(65+ MB/s) |
| 使用方式 | 构建完整 DOM 树 | 事件驱动(回调/队列/处理器) |
| 适用文档 | 小到中型(KB ~ MB) | 大型到超大型(MB ~ GB) |
| 编码支持 | UTF-8 | UTF-8 / UTF-16 / UTF-32(自动检测) |
| 随机访问 | 支持(遍历 DOM 树) | 不支持(流式顺序处理) |
## 性能表现
### DOM 解析器性能
在 Release 构建(-O3 优化)下的性能数据(Apple Silicon M2):
| 测试场景 | 文档大小 | 吞吐量 (MB/s) | 解析时间 | 说明 |
|---------|---------|--------------|----------|------|
| 小型文档 | 60 字节 | 36.46 | 0.002 ms | 基准测试 |
| 中型文档 | 3.58 KB | 236.23 | 0.015 ms | 基准测试 |
| 多属性文档 | 1.65 KB | 287.81 | 0.006 ms | 基准测试 |
| 无实体、无命名空间 | 24 MB | **642** | 37.34 ms | 理想场景 |
| 有实体、无命名空间 | 57 MB | **450** | 126.67 ms | 实体解析为主要瓶颈 |
| 有实体、有命名空间 | 62 MB | **421** | 147.27 ms | 全功能模式 |
| 混合(实体 + 命名空间) | 68 MB | **417** | 163.07 ms | 真实场景 |
**性能瓶颈分析**:
- **实体解析**:~30% 开销(主要瓶颈,涉及字符串累加和内存池拷贝)
- **文件大小**:~5% 开销(更多字符需要扫描)
- **命名空间解析**:< 1.5% 开销(几乎免费)
### 流式解析器性能
基于 66KB 文档(包含 1,000 个元素)的测试结果:
| 指标 | 数值 |
|------|------|
| 解析耗时 | **1 ms** |
| 吞吐量 | **65,248 KB/s** |
| 内存占用 | 恒定(可配置) |
### 典型场景性能预期(流式)
| 文档规模 | 预期解析时间 | 内存占用 |
|----------|-------------|----------|
| 1 MB | < 20 ms | < 256 KB |
| 10 MB | < 150 ms | < 512 KB |
| 100 MB | < 1.5 s | < 1 MB |
| 1 GB | < 15 s | < 2 MB |
*注:以上数据基于标准配置,实际性能取决于硬件和文档结构*
### 编译优化效果
Debug 构建与 Release 构建的性能对比:
| 构建类型 | 优化选项 | 相对性能 |
|---------|---------|---------|
| Debug | -O0, ASAN/UBSAN | 基准线 (1x) |
| Release | -O3, LTO, 架构优化 | **10-50x** |
Release 构建启用的优化:
- `-O3`:最高级别优化
- `-fomit-frame-pointer`:省略帧指针
- `-fstrict-aliasing`:严格别名规则
- `-funroll-loops`:循环展开
- `-finline-functions`:函数内联
- `-march=native`:CPU 特定指令集
- `-flto`:链接时优化
### 与同类库性能对比
LiteXML 在提供完整功能(命名空间 + 实体 + 错误处理)的同时,保持了优秀的解析性能。
**测试环境**:Apple Silicon M4,Release 构建(-O3),50 次迭代取平均值。
| 解析器 | 无实体 (24MB) | 有实体 (57MB) | 有实体+NS (62MB) | 混合 (68MB) | 命名空间 | 错误处理 | 内存安全 |
|--------|--------------|--------------|-----------------|------------|---------|---------|---------|
| **RapidXML** | **2450** | **1281** | **1280** | **1280** | ❌ 手动 | ❌ | ❌ |
| **pugixml** | **1442** | **789** | **759** | **787** | ✅ | ✅ | ✅ |
| **LiteXML** | **642** | **450** | **421** | **417** | ✅ | ✅ | ✅ |
| **TinyXML2** | 218 | 345 | ❌ 失败 | ❌ 失败 | ❌ | ✅ | ✅ |
> **注**:TinyXML2 在带命名空间的 XML 上解析失败(Dummy=0),数据为虚高(快速失败路径)。
### 解析器定位总结
| 解析器 | 定位 | 一句话总结 |
|--------|------|-----------|
| **RapidXML** | 极致性能 | 速度之王,但裸奔(无安全、无命名空间) |
| **pugixml** | 性能 + 功能 | 性能与功能的完美平衡 |
| **LiteXML** | 安全 + 易用 | 安全优先,性能够用 |
| **TinyXML2** | 简单入门 | 不适合高性能/复杂场景 |
### 功能完整性对比
| 功能 | RapidXML | pugixml | LiteXML | TinyXML2 |
|------|----------|---------|---------|----------|
| DOM 解析 | ✅ | ✅ | ✅ | ✅ |
| 流式解析 | ❌ | ❌ | ✅ | ❌ |
| 命名空间 | ❌ 手动 | ✅ | ✅ | ❌ |
| 实体解码 | ✅ | ✅ | ✅ | ✅ |
| 错误处理 | ❌ | ✅ | ✅ | ✅ |
| 内存安全 | ❌ | ✅ | ✅ | ✅ |
| 零拷贝设计 | ✅ | ❌ | 部分 | ❌ |
| 内存池 | ❌ | ❌ | ✅ | ❌ |
| C++23 现代接口 | ❌ | ❌ | ✅ | ❌ |
### 选型建议
| 你的需求 | 推荐 | 理由 |
|---------|------|------|
| **极致性能,输入可控,无实体** | **RapidXML** | 2450 MB/s,无人能敌 |
| **极致性能,输入可控,有实体** | **RapidXML** | 1281 MB/s,仍然最快 |
| **高性能 + 完整功能(命名空间/实体)** | **pugixml** | 759-1442 MB/s,功能完整 |
| **安全性优先 + 可接受的性能** | **LiteXML** | 421-642 MB/s,内存安全 + 错误处理 |
| **需要流式处理超大文件** | **LiteXML (流式)** | 恒定内存占用处理 GB 级文档 |
| **教学/简单工具,XML 无命名空间** | **TinyXML2** | API 简单,但性能最差 |
---
## 技术架构
### DOM 解析器解析流程
```
输入 XML
↓
解析 Prolog(可选)
↓
解析内容
├── 元素节点
│ ├── 属性解析
│ ├── 命名空间解析
│ └── 子节点递归
├── 文本节点(优化合并)
├── CDATA 段
├── 注释(可配置)
└── 处理指令(可配置)
↓
构建 DOM 树
↓
返回文档对象
```
### 流式解析器架构
```
输入 XML(任意编码)
↓
编码自动检测(BOM / 声明)
↓
缓冲区管理(可配置大小 + 预取)
↓
事件驱动解析
├── start_element(含命名空间)
├── end_element
├── text(可合并)
├── cdata
├── comment
└── processing_instruction
↓
三种使用模式:
├── 回调函数
├── 事件队列
└── 处理器接口(推荐)
```
### 核心组件
| 组件 | DOM 解析器 | 流式解析器 |
|------|-----------|-----------|
| 解析器主类 | `XMLParser` | `StreamParser` |
| 文档根节点 | `DocumentNode` | — |
| 元素节点 | `ElementNode` | `ElementInfo`(事件) |
| 内存管理 | `DocumentAllocator` | 可复用缓冲区 |
| 文本处理 | `TextAccumulator` | 批量文本合并 |
### DOM 内存管理
```
DocumentAllocator
├── 内存块 (64KB)
│ ├── 分配区域
│ └── 对齐处理
├── 节点分配
│ ├── ElementNode
│ ├── TextNode
│ ├── CDataNode
│ └── CommentNode
└── 字符串驻留
└── string_view 引用
```
---
## 可靠性
### 错误处理
- 完整的错误类型枚举
- 精确的错误位置信息(行号/列号/偏移量)
- 优雅的错误恢复
- 深度限制保护(DOM)和嵌套限制(流式)
### 内存安全
- 禁止拷贝构造和赋值
- RAII 资源管理
- 析构时自动清理树结构
- AddressSanitizer 和 UndefinedBehaviorSanitizer 支持
### 测试覆盖
- 20+ 功能测试用例
- 边界条件测试
- 错误路径测试
- 性能基准测试
- 内存泄漏测试
---
## 适用场景
| 场景 | 推荐模式 | 理由 |
|------|---------|------|
| 小型配置文件解析 | DOM | 快速、方便 |
| 大型 XML 数据导入 | 流式 | 内存可控 |
| 网络流式 XML | 流式 | 低延迟、逐事件 |
| 实时系统 | 两者皆可 | 根据文档大小选择 |
| 嵌入式/IoT 设备 | 流式 | 内存受限 |
| 批量处理(大量小文件) | DOM | 吞吐量最高 |
| 数据转换/ETL | 流式 | 适合大文件顺序处理 |
---
## 构建系统
### 支持的平台
- macOS (Apple Silicon)
- Linux (x86_64, ARM)
- Windows (MSVC)
### 构建选项
- 静态库 / 动态库
- Debug / Release / RelWithDebInfo / MinSizeRel
- AddressSanitizer 支持 (Debug)
- UndefinedBehaviorSanitizer 支持 (Debug)
- LTO 支持 (Release, Linux)
### 编译器要求
- Clang 16+
- GCC 12+
- MSVC 2022+
---
## 性能优化建议
### DOM 模式
1. **关闭不必要的功能**:如不需要命名空间,设置 `config.parseNamespaces = false`
2. **跳过注释**:`config.parseComments = false`
3. **跳过处理指令**:`config.parseProcessingInstructions = false`
### 流式模式
1. **配置缓冲区大小**:根据文档大小调整 `config.buffer_size`
2. **启用预取**:`config.prefetch_data = true`
3. **禁用不必要的验证**:生产环境可关闭 `config.validate_names`
4. **合并文本节点**:`config.coalesce_text = true`
5. **使用事件处理器接口**:比回调方式开销更小
---
## 总结
LiteXML 是一个为现代 C++ 应用设计的高性能 XML 解析库。通过采用零拷贝设计、内存池技术、编译时优化以及流式架构,它在保持代码简洁和可维护性的同时:
- **DOM 模式**:实现 400+ MB/s 的解析吞吐量,全功能模式下可达 417 MB/s,适合中小型文档
- **流式模式**:以恒定内存占用(< 2 MB)处理 GB 级文档,适合大型数据集
无论是用于高性能服务器、嵌入式系统、实时应用,还是大规模数据导入,LiteXML 都能提供可靠、高效的 XML 解析能力。
---
**版本**:2.0.0
**语言**:C++23
**许可**:MIT
**作者**:_huanhuan_