Apache Xalan-C++ 介绍与选型指南
Apache Xalan-C++ 项目定位、版本现状与选型分析:XSLT 1.0/XPath 1.0 处理器的 C++ 实现,与 Xerces-C++ 的依赖关系,与 Xalan-J、libxslt 的横向对照,基于 Ubuntu 22.04 源码构建与 21 项自测全通过的真实结论。
Apache Xalan-C++ 介绍与选型指南
目标:说清楚 Apache Xalan-C++ 是什么、版本与维护现状如何、依赖谁、与同门兄弟 Xalan-J 以及社区另一主流 C/C++ 方案 libxslt 怎么选。本文所有结论均来自 Ubuntu 22.04 服务器上的真实源码构建与功能实测(21 项 ctest 全通过),实测环境与构建细节见《Apache Xalan-C++ 在 Ubuntu 22.04 集成使用指南》。
一、项目定位:Xalan-C++ 是什么
1.1 一句话定义
Xalan-C++ 是 Apache Xalan 项目旗下的 C++ 语言 XSLT 处理器,实现 XSLT 1.0 与 XPath 1.0 两个 W3C 推荐标准,名字取自一种稀有的音乐器官移植手术术语(Xalan-Envoy,项目命名梗)。它与 Xerces-C++(Apache 的 XML 解析器)配套使用:Xerces 负责 XML 解析,Xalan 负责在其上执行 XSLT 变换与 XPath 求值。
💡 技术拓展:Xalan 项目名称源于 "Xalan-Envoy" 一种稀有的鹦鹉螺目软体动物。项目包含两大实现:Xalan-Java(Java 版,本专栏已有《Ubuntu 22.04 安装 Apache Xalan 指南》专文)与 Xalan-C++(本文主角)。两者 API 完全独立、代码零共享,只是共享 "Xalan" 品牌与 XSLT 1.0 兼容性目标。
1.2 版本与维护现状(如实披露)
实测以官方发布页为准(xalan.apache.org/xalan-c/releases.html,现重定向到 apache.github.io/xalan-c/):
| 项目 | 事实 |
|---|---|
| 最新正式版本 | 1.12,发布于 2020-06-07 |
| 下一版本 1.13 | 官方页面标注计划中,至今尚未发布 |
| 库版本号 | 1.12 对应库主版本 112(产物为 libxalan-c.so.112.0,实测确认) |
| 支持标准 | XSLT 1.0、XPath 1.0(不支持 XSLT 2.0/3.0) |
| 官网镜像文档 | https://xalan.apache.org/xalan-c/ (重定向至 apache.github.io/xalan-c api 文档) |
💡 技术拓展:判断一个 C/C++ 库的"活跃度"不能只看最近一次 release 时间。Xalan-C++ 1.12 之后主干仍有零星提交与 issue 修复,但没有进入 1.13 的正式发布节奏。选型时应把它当作成熟稳定、低频维护的组件,而不是持续快速演进的项目。
1.3 构建系统与源码结构
1.12 采用 CMake 作为唯一构建入口(实测源码顶层 CMakeLists.txt):
cmake_minimum_required(VERSION 3.2.0)
project(xalan-c
VERSION 1.12.0
LANGUAGES C CXX)
源码树核心目录(实测解压后清单):
| 目录 | 内容 |
|---|---|
| src/xalanc/ | 库主体源码(XSLT、XPath、DOM 支撑、转码、消息) |
| src/xalanc/TestXSLT/ | Xalan 命令行工具源码 |
| src/xalanc/TestXPath/ | XPath 自测工具源码 |
| src/xalanc/Utils/MsgCreator/ | 消息编译器(构建期生成消息库) |
| samples/ | 16 个官方样例源码 |
| Tests/ | Conf 与 Performance 回归/性能工具 |
| cmake/ | 18 个 CMake 模块(转码器/线程/消息加载器选择等) |
| docs/doxygen | API 文档生成配置 |
💡 技术拓展:构建期会先编译一个名为 MsgCreator 的小工具,用扫描源码里的消息 ID 生成
XalanMsgLib(即 libxalanMsg),这是"消息与引擎分离"设计的来源。选 inmemory 消息加载器时消息直接编进库内存段,选 NLS/ICU 加载器则走外部资源——但后两者在上游 CMake 选项名里直接标注了 broken(实测选项值nls-broken/icu-broken),生产环境老实用默认的 inmemory。
1.4 实测版本自证
构建安装后,命令行工具自带版本横幅,Xalan -? 的前两行就是版本信息(完整 -h 输出见《Apache Xalan-C++ 1.12 常用 CLI 命令与工具详解》):
Xalan version 1.12.0.
Xerces version 3.2.3.
头文件 xalanc/Include/XalanVersion.hpp 中的版本宏(实测摘录):
#define XALAN_VERSION_MAJOR (1)
#define XALAN_VERSION_MINOR (12)
#define XALAN_VERSION_REVISION (0)
#define _XALAN_VERSION ((10000 * XALAN_VERSION_MAJOR) + (100 * XALAN_VERSION_MINOR) + XALAN_VERSION_REVISION)
版本守卫写法 #if _XALAN_VERSION >= 011000(即 1.10.0)在上游样例中实际使用,业务代码可用同一宏做版本分支。
二、与 Xerces-C++ 的依赖关系
2.1 依赖结构
Xalan-C++ 不含 XML 解析器,所有 XML 词法/语法解析都委托给 Xerces-C++。两者的关系是"处理器引擎 + 解析底座":
| 层 | 组件 | 职责 |
|---|---|---|
| 应用层 | 你的 C++ 程序 | 调 XalanTransformer API |
| 变换层 | libxalan-c + libxalanMsg | XSLT 编译执行、XPath 求值、结果序列化 |
| 解析层 | libxerces-c | SAX/DOM 解析、编码处理、校验 |
| 可选层 | ICU (libicu) | 转码与消息加载的增强后端(可选) |
2.2 版本兼容实测
Xalan-C++ 1.12 的 CMake 构建脚本对 Xerces 的硬性要求(实测源码 cmake/XalanXerces.cmake):
find_package(XercesC 3.1 REQUIRED)
而 Ubuntu 22.04 官方仓库的 Xerces 包版本(实测 dpkg -l libxerces-c-dev):
libxerces-c-dev:amd64 3.2.3+debian-3ubuntu0.1
CMake 探测结果(构建配置阶段实际回显):
-- Found XercesC: /usr/lib/x86_64-linux-gnu/libxerces-c.so (found suitable version "3.2.3", minimum required is "3.1")
结论:官方文档口径是"支持 Xerces-C++ 3.0+(首选 3.2.3)",但 1.12 的 CMake 构建实际要求 3.1 及以上。Ubuntu 22.04 的 3.2.3 直接满足,无需额外处理。
💡 技术拓展:Xalan 与 Xerces 的运行时初始化必须成对出现——
XMLPlatformUtils::Initialize()(Xerces)+XalanTransformer::initialize()(Xalan),退出时XalanTransformer::terminate()+XMLPlatformUtils::Terminate(),若集成了 ICU 还要补XalanTransformer::ICUCleanUp()。顺序搞反或作用域不当会段错误,实测细节见《Apache Xalan-C++ 1.12 配置参数详解》生命周期一节。
2.3 ICU 是可选依赖
实测环境装有 ICU 70.1,CMake 自动探测并把默认转码器切到 icu:
-- Found ICU: /usr/include (found version "70.1")
-- Transcoder: icu
没有 ICU 也能构建——转码器会回落到 default(操作系统本地转码)。ICU 只增强字符集覆盖与本地化消息能力,不是硬依赖。
三、横向选型对照:Xalan-C++ vs Xalan-J vs libxslt
3.1 三者对照表
| 维度 | Xalan-C++ 1.12 | Xalan-J 2.7.3 | libxslt(xsltproc) |
|---|---|---|---|
| 语言/运行时 | C++ 原生库 | Java(需 JVM) | C 原生库 |
| XSLT 支持 | 1.0 | 1.0 | 1.0 + EXSLT 扩展 |
| XPath 支持 | 1.0 | 1.0 | 1.0 + EXSLT 函数 |
| 维护状态 | 成熟稳定,最后正式发布 2020-06,1.13 未发布 | 低频维护(本专栏实测 2.7.3 为 Maven Central 在线版本) | 社区活跃,持续发版 |
| 依赖 | Xerces-C++ 3.1+(可选 ICU) | JAXP/Xerces-J、JDK | libxml2 |
| 进程内嵌 | 适合(原生 so) | 适合 JVM 技术栈 | 适合(原生 so) |
| 独立 CLI | Xalan(随库安装) | 需自行包装或用 java -jar | xsltproc 开箱即用 |
| 构建方式 | CMake(源码编译) | Maven/Gradle 引入 | 系统仓库直装 |
3.2 怎么选:按场景给结论
选 Xalan-C++ 的场景:
- 已有 Xerces-C++ 技术栈:需要在同一进程内既做 DOM 解析又做 XSLT 变换,且希望变换结果能直接对接 Xerces DOM(Xalan 提供 TransformToXercesDOM 能力,实测样例可跑通)。
- Apache 生态一致性要求:合规或架构规范要求 XML 全家桶统一 Apache 系(Xerces + Xalan),避免混入 GNOME 系的 libxml2/libxslt。
- 需要 XSLT 处理器的源码级可维护性:Xalan-C++ 代码结构清晰、样例齐全(16 个官方样例实测可构建可运行),适合需要深度定制或审计源码的团队。
不选 Xalan-C++ 的场景:
- 需要 XSLT 2.0/3.0:直接看 libxslt(1.0+EXSLT)之外的 Saxon 系(Java/C 版 saxonc),Xalan-C++ 1.0 语义是硬边界。
- 只要命令行转换、不想编译:
apt install xsltproc五秒可用,没必要为一个转换任务从源码编译 Xalan。 - 需要强活跃度的社区与快速 bug 响应:libxslt 的发版节奏远快于 Xalan-C++。
Xalan-J 的定位:已在 JVM 技术栈内(Java 服务、Tomcat 应用)需要 XSLT 时它最顺路,API 通过 JAXP 标准接口接入,细节见本专栏《Ubuntu 22.04 安装 Apache Xalan 指南》。C++ 进程内嵌场景它与 Xalan-C++ 无可替代性重叠。
3.3 一个容易被忽略的选型事实:库体积与产物
实测 1.12 构建产物大小:
| 文件 | 大小(实测 ls -l) |
|---|---|
| libxalan-c.so.112.0 | 5,761,640 字节(约 5.5 MB) |
| libxalanMsg.so.112.0 | 55,280 字节(约 54 KB) |
两个 so 是"引擎 + 消息资源"分离设计:libxalanMsg 只装错误消息文本,便于独立做本地化。这个结构意味着升级消息包不需要动引擎库。
四、核心组成与能力地图
4.1 组件清单(全部实测验证存在且可运行)
| 组件 | 形态 | 用途 | 实测验证方式 |
|---|---|---|---|
| XalanTransformer API | C++ 库接口 | 进程内 XSLT 变换、参数注入、错误处理 | 自写 simple_transform.cpp 编译运行通过 |
| Xalan(TestXSLT) | CLI 可执行 | 命令行 XSLT 转换 | 10 组参数逐项实测 |
| TestXPath | CLI 可执行 | XPath 求值自测工具 | 运行输出 17 组表达式结果 |
| MsgCreator | 构建期工具 | 生成本地化消息库源码 | 构建系统内部使用 |
| Conf / Performance | 测试工具 | 回归与性能基准(需外部测试数据) | 运行打印用法后正常退出 |
| 16 个官方样例 | 源码 + 可执行 | API 用法示范 | ctest 21 项全通过 |
| 头文件 15 个子目录 | /usr/local/include/xalanc/ | 二次开发 | pkg-config/编译实测 |
头文件子目录实测清单(ls /usr/local/include/xalanc/):
DOMSupport Harness ICUBridge Include
PlatformSupport XMLSupport XPath XPathCAPI
XSLT XalanDOM XalanEXSLT XalanExtensions
XalanSourceTree XalanTransformer XercesParserLiaison
4.3 官方样例一览(16 个,全部随构建产出)
实测构建产物中的样例可执行文件(构建目录 samples/ 下):
| 样例 | 语言 | 演示主题 |
|---|---|---|
| XalanTransform | C++ | 最小变换:两行 API 完成文件到文件的 XSLT |
| SimpleTransform | C++ | 简化版变换 + 自定义内存管理器 |
| StreamTransform | C++ | 流式输入输出变换(实测输出 <?xml version="1.0" encoding="US-ASCII"?><out>Hello world!</out>) |
| CompileStylesheet | C++ | 预编译样式表复用(1 份样式表对 10 份 XML) |
| UseStylesheetParam | C++ | 三类顶层参数注入:字符串/数值/节点集 |
| DocumentBuilder | C++ | 用 Xalan 的 DOM 实现构建文档 |
| EntityResolver | C++ | 自定义实体解析回调 |
| ExternalFunction | C++ | 在 XPath 中调用外部 C++ 函数 |
| ParsedSourceWrappers | C++ | 包装 Xerces DOM / SAX 流作为变换输入 |
| SerializeNodeSet | C++ | XPath 选中节点集的序列化输出 |
| SimpleXPathAPI | C++ | XPath 表达式求值完整闭环 |
| SimpleXPathCAPI | C | 纯 C 语言接入 XPath 的演示 |
| TraceListen | C++ | 四种执行跟踪监听器(-tt/-tg/-ts/-ttc) |
| TransformToXercesDOM | C++ | 变换结果直接产出 Xerces DOM 树 |
| ThreadSafe | C++ | 多线程各持独立 Transformer 并发变换 |
| XalanTransformerCallback | C++ | 变换过程回调(格式化/输出接管) |
另有 ApacheModuleXSLT(Apache HTTP Server 模块)与 XPathWrapper(Python 绑定旧封装)两个目录存在于源码树,但 1.12 的 CMake 构建未将它们纳入编译目标(实测 samples/CMakeLists.txt 的构建清单只有上表 16 个),源码层面可参考、不可开箱即用。
4.4 能力边界
- 线程模型:XalanTransformer 实例不是线程安全的,多线程需每线程一个实例;官方 ThreadSafe 样例实测三线程并发跑通(各用独立 transformer)。
- EXSLT:XalanEXSLT 头目录存在,提供部分 EXSLT 扩展函数,但覆盖面与 libxslt 的 EXSLT 实现不一一对应,依赖具体扩展函数前需逐一验证。
- C API:提供 XPathCAPI(纯 C 接口样例 SimpleXPathCAPI 实测通过),适合 C 语言项目接入,但主 API 面向 C++。
- 输出格式:XML / HTML / TEXT 三种输出方法(CLI 源码与 API 均可指定),HTML 输出的 META 标签、URL 转义行为可通过参数控制。
五、实测验证摘要
5.1 实测环境
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(x86_64) |
| 编译器 | gcc/g++ 11.4.0 |
| 构建系统 | cmake 3.22.1 |
| Xerces-C++ | 3.2.3+debian-3ubuntu0.1(apt 官方仓库) |
| ICU | 70.1(系统自带) |
| Xalan-C++ | 1.12(源码编译,CMAKE_BUILD_TYPE=Release) |
| 实验目录 | /root/xalan_c-1.12、/root/xalan_c-1.12-build |
| 管理账号 | root(密码 q1w2e3r4) |
5.2 关键验证结论
- 构建干净度:GCC 11 全量编译,
grep error:计数为 0,告警集中在-Wdeprecated-copy(XalanList.hpp 迭代器自赋值模式与 C++11 语义冲突),不影响产物正确性。若项目全局开了-Werror需要为该头文件路径加豁免。 - 功能自测:
ctest21/21 全部通过,覆盖 16 个样例与 TraceListen 四种跟踪模式的组合场景。实测末尾输出:
100% tests passed, 0 tests failed out of 21
Total Test time (real) = 0.26 sec
- 命令行完整性:Xalan CLI 共 10 个选项 + stdin 输入,全部实测有效;转换成功退出码 0,转换错误 254,用法/帮助 255(补测确认)。
- 发现的平台瑕疵:随库安装的
pkg-config xalan-c文件 Version 字段为空(实测pkg-config --modversion xalan-c返回空串),依赖它做版本检测的构建脚本会拿不到版本号,应改读XalanVersion.hpp的版本宏。 - API 最小闭环:手写 30 行 C++ 完成"加载 XML + XSLT → 输出 HTML"全流程,编译命令只需
-I/usr/local/include -lxalan-c -lxalanMsg -lxerces-c三件套。 - 参数注入语义:字符串参数按 XPath 表达式解析(实测传裸字符串报
XPath error: Extra illegal token,必须写成'text'带引号形式),这是从其他 XSLT 库迁移过来最容易踩的语义差异。
六、选型决策速查
你的需求是什么?
├── C++ 进程内 XSLT 1.0 + 已用 Xerces → Xalan-C++ 1.12 ✔
├── C++ 进程内 XSLT 1.0 + 无历史包袱 → libxslt 优先,Xalan-C++ 备选
├── Java/JVM 技术栈 → Xalan-J 2.7.3(JAXP 接入)
├── 纯命令行偶发转换 → xsltproc
└── 需要 XSLT 2.0/3.0 → 三者都不行,看 Saxon 系
最后提醒一点工程现实:Xalan-C++ 1.12 的源码在 GCC 11 下编译有大量 deprecation 告警,这代表代码风格停留在 C++03/C++11 过渡期。能接受这一点(通常都能),它就是 Apache 系 XML 栈里最正统的 C++ XSLT 选择。
七、参考链接
- Xalan-C++ 官方主页:https://xalan.apache.org/xalan-c/
- 版本发布页(1.12,2020-06-07):https://xalan.apache.org/xalan-c/releases.html
- 源码下载(Apache 归档):https://archive.apache.org/dist/xalan/xalan-c/sources/xalan_c-1.12.tar.gz
- Xerces-C++ 官方主页:https://xerces.apache.org/xerces-c/
- W3C XSLT 1.0 规范:https://www.w3.org/TR/1999/REC-xslt-19991116
- W3C XPath 1.0 规范:https://www.w3.org/TR/1999/REC-xpath-19991116
- 本专栏相关文档:《Apache Xalan-C++ 在 Ubuntu 22.04 集成使用指南》《Apache Xalan-C++ 1.12 配置参数详解》《Apache Xalan-C++ 1.12 常用 CLI 命令与工具详解》