Apache Xalan-J 介绍与选型指南

"Apache Xalan-J 2.7.3 详解:XSLT 1.0 处理器定位、与 JDK 内置 Xalan 的关系辨析、xsltc 编译器等独立使用价值,以及与 Saxon 的选型对比,全部结论基于 Ubuntu 22.04 + JDK 17 真机实测。"

Apache XalanApache XalanJavaXMLXSLTApache2026/10/16

Apache Xalan-J 介绍与选型指南

目标:读完本文,你能够搞清楚 Apache Xalan-J 是什么、它与 JDK 内置 Xalan 是什么关系、独立部署 Xalan-J 能带来哪些 JDK 内置实现不具备的能力,并能在 Xalan-J、JDK 内置 Xalan 与 Saxon 之间做出有依据的选型。文中所有结论均来自 Ubuntu 22.04 服务器上 JDK 17 环境的真实运行结果,而非文档转述。

一、环境信息

项值
操作系统Ubuntu 22.04.5 LTS(x86_64)
JDKOpenJDK 17.0.20.1(Ubuntu 发行版)
构建工具Apache Maven 3.6.3
Xalan-J 版本2.7.3(官方二进制包 xalan-j_2_7_3-bin.tar.gz)

查看本机环境的真实命令与回显:

$ head -2 /etc/os-release
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
$ uname -m
x86_64
$ java -version 2>&1
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
$ mvn -version 2>&1 | head -4
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968

💡 技术拓展:platform encoding: ANSI_X3.4-1968 是 POSIX locale 的别名。最小化安装的系统常缺 UTF-8 locale,会导致 Java 程序往控制台输出中文变成问号。解决办法是 export LANG=C.UTF-8(C.UTF-8 是 Ubuntu 内置的 locale,无需额外安装语言包)。后文所有实测输出都已在该变量设置后采集。

Xalan-J 的最新稳定版本经两处交叉确认:

$ curl -s https://repo1.maven.org/maven2/xalan/xalan/maven-metadata.xml | grep -E "<latest>|<release>"
    <latest>2.7.3</latest>
    <release>2.7.3</release>

Maven Central 的 latest 与 release 均为 2.7.3(2023-03-25 构建,官方站点同版本发布说明)。本文全部实测基于该版本。

二、软件概述

Apache Xalan-J 是 Apache Xalan 项目的 Java 实现,是一个符合 XSLT 1.0 与 XPath 1.0 规范的处理器:读取 XML 文档与 XSLT 样式表,输出 HTML、XML 或纯文本。它同时提供两种运行形态:

形态机制入口
解释执行运行时逐条解释样式表org.apache.xalan.xslt.Process(命令行)/ org.apache.xalan.processor.TransformerFactoryImpl(API)
编译执行(XSLTC)把样式表编译成 Java 字节码 translet 再运行org.apache.xalan.xsltc.cmdline.Compile / Transform / org.apache.xalan.xsltc.trax.TransformerFactoryImpl

两者都实现标准 JAXP(javax.xml.transform)接口,因此同一个 Java 程序不改一行代码即可在两种引擎间切换——切换的只是类路径上的工厂实现。

Xalan-J 2.7.3 官方二进制包解压后共四个 jar:

jar大小(字节)作用
xalan.jar3455761双引擎本体(解释器 + XSLTC)
serializer.jar283536序列化器(HTML/XML/Text 输出)
xercesImpl.jar1446149Xerces-J XML 解析器
xml-apis.jar228394DOM/SAX/JAXP 标准 API

三、核心架构

3.1 引擎信息实测

用样式表输出 system-property('xsl:vendor') 与 xsl:vendor-url,可以精确区分当前跑的是哪个引擎(engine-info.xsl 为打印这两个属性的样式表):

属性独立 Xalan-J(解释器工厂)JDK 17 内置引擎
xsl:vendorApache Software FoundationApache Software Foundation (Xalan XSLTC)
xsl:vendor-urlhttp://xml.apache.org/xalan-jhttp://xml.apache.org/xalan-j
$ java -cp classes:$CP EngineInfo
TransformerFactory 实现类: org.apache.xalan.processor.TransformerFactoryImpl
xsl:version    = 1.0
xsl:vendor     = Apache Software Foundation
xsl:vendor-url = http://xml.apache.org/xalan-j

💡 技术拓展:xsl:vendor 是 XSLT 1.0 规范定义的系统属性,任何兼容处理器都必须支持。JDK 内置实现的 vendor 字符串里带 "(Xalan XSLTC)" 后缀,而独立 Xalan-J 的解释器工厂只报 "Apache Software Foundation"——这是区分两者的最可靠方法。

3.2 发行包 Manifest 自带启动坐标

$ unzip -p /root/xalan-j_2_7_3/xalan.jar META-INF/MANIFEST.MF | grep -E "Implementation-Version|Implementation-Vendor|Main-Class"
Main-Class: org.apache.xalan.xslt.Process
Implementation-Version: 2.7.3
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 2.7.3
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 2.7.3
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 2.7.3
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 2.7.3
Implementation-Vendor: Princeton University
Implementation-Version: 2.7.3
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 2.7.3
Implementation-Vendor: Apache Software Foundation
$ unzip -p /root/xalan-j_2_7_3/xalan.jar META-INF/MANIFEST.MF | grep -A1 "Class-Path" | head -2
Class-Path: xercesImpl.jar xml-apis.jar serializer.jar

两个关键信息:Main-Class 是命令行入口(java -jar xalan.jar 直接可用);Class-Path 声明了三个兄弟 jar——把 xalan.jar 与发行包其余三个 jar 放在同一目录时,无需手动拼类路径(Manifest Class-Path 会按相对路径自动加载),这在手动 jar 集成时非常关键,详见《Apache Xalan-J 在 Ubuntu 22.04 集成使用指南》。

(Manifest 里的实现版本对出现多次,是因为清单文件按打包来源分了多个节段,各节段都标注了构建版本与来源方,其中 Princeton University 节段对应 XSLTC 的学术来源。)

四、关键能力实测

4.1 命令行一键变换

$ java -cp $CP org.apache.xalan.xslt.Process -IN hello.xml -XSL hello.xsl
<?xml version="1.0" encoding="UTF-8"?><message>Hello, Xalan-J! Your XSLT engine is Apache Software Foundation.</message>

4.2 XSLTC 编译执行

$ java -cp $CP org.apache.xalan.xslt.Process -XSLTC -IN hello.xml -XSL hello.xsl
<?xml version="1.0" encoding="UTF-8"?><message>Hello, Xalan-J! Your XSLT engine is Apache Software Foundation (Xalan XSLTC).</message>
$ java -cp $CP org.apache.xalan.xslt.Process -XSLTC -XO hello -XSL hello.xsl && ls -l hello.class
-rw-r--r--  1 root root 3267 Oct 16 00:51 hello.class
$ java -cp $CP:. org.apache.xalan.xsltc.cmdline.Transform hello.xml hello
<?xml version="1.0" encoding="UTF-8"?><message>Hello, Xalan-J! Your XSLT engine is Apache Software Foundation (Xalan XSLTC).</message>

先编译成 translet(hello.class),再用 Transform 加载执行,输出一致。命令行工具的全部参数见《Apache Xalan-J 命令行工具详解》。

4.3 Java 扩展与 EXLT 扩展函数

独立 Xalan-J 默认放行 Java 扩展(样式表里直接调用 java.lang.Math 等类)与 EXLT 扩展(exslt:node-set 等):

$ java -cp classes:$CP Generic exslt-test.xsl employees.xml
<?xml version="1.0" encoding="UTF-8"?><report>
<java-ext>
<sqrt2>1.4142135623730951</sqrt2>
<round>3</round>
</java-ext>
<exslt>
<node-set-count>2</node-set-count>
<first-item>XSLT 1.0</first-item>
</exslt>
</report>

同一个样式表跑在 JDK 内置引擎上同样能出结果(输出缩进为 4 空格、由内置引擎的序列化器排版),说明两套引擎在扩展支持上的差异主要体现在默认安全策略上——见 4.5 的 -SECURE 实测。

4.4 trace 调试与诊断计时

$ java -cp $CP org.apache.xalan.xslt.Process -TT -IN hello.xml -XSL hello.xsl
null Line #0, Column #0: template match='/' 
file:///root/xalan-lab/hello.xsl Line #4, Column #35: template match='/greeting' 
<?xml version="1.0" encoding="UTF-8"?><message>Hello, Xalan-J! Your XSLT engine is Apache Software Foundation.</message>
$ java -cp $CP org.apache.xalan.xslt.Process -DIAG -IN employees.xml -XSL employees2html.xsl
 --------- Transform of employees.xml via employees2html.xsl took 102 ms
$ java -cp $CP org.apache.xalan.xslt.Process -DIAG -XSLTC -IN hello.xml -XSL hello.xsl
 --------- Transform of hello.xml via hello.xsl took 55 ms

(-TT 的 trace 行与变换结果混在同一输出流,行尾空格为监听器打印格式,均照实录转述。-DIAG 的耗时受机器状态影响,此处数字仅代表本机当次运行。)

4.5 安全处理开关对 Java 扩展的拦截

$ java -cp $CP org.apache.xalan.xslt.Process -SECURE -IN employees.xml -XSL exslt-test.xsl
<?xml version="1.0" encoding="UTF-8"?><report>
<java-ext>(Location of error unknown)Extension function: '{http://xml.apache.org/xalan/java/java.lang.Math}sqrt' can not be invoked when the XMLConstants.FEATURE_SECURE_PROCESSING feature is set to true.

-SECURE 开启后 Java 扩展函数调用被直接拒绝(退出码 0,但输出中断在 java-ext 节点)。这是不可信样式表场景的标准防线,详见《Apache Xalan-J 2.7.3 配置参数详解》5.4 节。

五、与 JDK 内置 Xalan 的关系辨析

JDK 自带的 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl 正是从 Xalan-J XSLTC 引擎衍生并内置的版本。三者的关系:

$ java -cp classes HelloXalan            # 类路径上没有 xalan.jar
TransformerFactory 实现类: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
<?xml version="1.0" encoding="UTF-8"?><message>Hello, Xalan-J! Your XSLT engine is Apache Software Foundation (Xalan XSLTC).</message>
$ java -cp classes:$CP HelloXalan        # 把独立 Xalan-J 放进类路径
TransformerFactory 实现类: org.apache.xalan.processor.TransformerFactoryImpl
<?xml version="1.0" encoding="UTF-8"?><message>Hello, Xalan-J! Your XSLT engine is Apache Software Foundation.</message>

(HelloXalan 为调用 TransformerFactory.newInstance() 后打印实现类并执行一次 hello 变换的最小程序。)

实测结论:

  1. 不用任何依赖时,JDK 内置实现接管:TransformerFactory.newInstance() 落到 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl,功能完整,普通 XSLT 1.0 变换无需引入 Xalan-J。
  2. 类路径放上 xalan.jar 即整体切换:SPI 文件(META-INF/services/javax.xml.transform.TransformerFactory)随 jar 生效,newInstance() 改落 org.apache.xalan.processor.TransformerFactoryImpl(解释器引擎),输出文本中的引擎标识随之变化。
  3. 独立 Xalan-J 的增量价值:
    • 解释器引擎(JDK 内置只有 XSLTC 衍生品,没有解释器引擎);
    • 可控的升级节奏(JDK 内置版本与 JDK 绑定,2.7.3 修复项需独立引入才能获得);
    • 命令行工具与 XSLTC 预编译链路的完整发行包;
    • 与 JDK 内置实现在输出属性、扩展函数策略上的行为差异(如 accessExternal* 属性仅 JDK 内置支持,实测见《Apache Xalan-J 2.7.3 配置参数详解》)。
  4. 风险差异:在 JDK 17 上反射直接实例化 JDK 内部工厂类会被模块封装拒绝:
D. 反射实例化被 JDK 17 模块封装拒绝: java.lang.IllegalAccessException
   原因: module java.xml does not export com.sun.org.apache.xalan.internal.xsltc.trax
   绕行: java --add-exports java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED ...

绕行后可正常探测 JDK 内置工厂的属性(真实回显节选):

setAttribute(http://javax.xml.XMLConstants/property/accessExternalStylesheet, file) 成功
setAttribute(http://javax.xml.XMLConstants/property/accessExternalDTD, all) 成功
setAttribute(http://www.oracle.com/xsl/jaxp/transform/feat/enable-extension-functions) 拒绝: TransformerFactory does not recognise attribute 'http://www.oracle.com/xsl/jaxp/transform/feat/enable-extension-functions'.

六、适用场景与限制

6.1 适合用独立 Xalan-J 的场景

  1. 需要解释器引擎的渐进式处理能力(大文档交互渲染,配合 features/incremental 属性);
  2. 需要锁定与 JDK 版本无关的 Xalan 行为基线(升级 JDK 不改变 XSLT 引擎版本);
  3. 需要命令行工具或 XSLTC 预编译产物(translet 类文件 / jar)分发;
  4. 需要默认放行 Java 扩展函数的遗留系统迁移(JDK 内置引擎对扩展的控制粒度更严)。

6.2 已实测确认的限制

  1. XSLT 1.0 边界:不支持 XSLT 2.0/3.0,正则、分组、日期时间等 2.0 特性一律不可用;
  2. Maven 单依赖不完整:仅引入 xalan:xalan:2.7.3 运行时报 NoClassDefFoundError: org/apache/xalan/transformer/TransformerImpl(实测,因解释器引擎核心类链接需要 serializer.jar 中的接口,详见《Apache Xalan-J 在 Ubuntu 22.04 集成使用指南》),必须成对引入 xalan:serializer:2.7.3;
  3. 脚本扩展依赖 BeanShell:需要额外引入 bsf/bsh 依赖,未引入时报类缺失;
  4. indent-amount 扩展键不生效:输出缩进粒度由样式表排版决定(实测见《Apache Xalan-J 2.7.3 配置参数详解》5.3 节)。

七、同类方案选型对比

维度Xalan-J 2.7.3Saxon-HE 13.1JDK 内置 Xalan
XSLT 版本1.02.0/3.0(HE 开源)1.0(XSLTC 衍生)
引擎形态解释器 + 编译器双引擎解释器 + 编译器双引擎仅 XSLTC 编译引擎
Java 扩展默认放行,-SECURE/FEATURE_SECURE_PROCESSING 可关受配置控制受配置控制,accessExternal* 白名单更细
许可Apache License 2.0Mozilla MPL 2.0(HE 版)JDK 随附
运行基线JDK 8+(本文实测 17)JDK 11+(实测 13.1 需 17 亦可)随 JDK
适用XSLT 1.0 遗留系统维护、需锁定行为新项目、需要 2.0/3.0不引依赖的最小场景

(Saxon-HE 的版本与许可信息以其官方发布页为准;本表仅作选型指引,未做 Saxon 的行为级实测。)

选型建议:新项目优先 Saxon(XSLT 2.0/3.0 能力)或直接用 JDK 内置(1.0 需求且不引依赖);维护既有 XSLT 1.0 资产、需要独立升级引擎版本或使用 XSLTC 预编译分发时,独立 Xalan-J 2.7.3 是正确选择。

八、参考链接

  1. Xalan-J 官方主页:https://xalan.apache.org/xalan-j/
  2. 版本发布说明:https://xalan.apache.org/xalan-j/download.html
  3. Maven Central 坐标:https://repo1.maven.org/maven2/xalan/xalan/
  4. Xalan-J 命令行工具参考:https://xalan.apache.org/xalan-j/commandline.html
  5. 《Apache Xalan-J 在 Ubuntu 22.04 集成使用指南》——安装与集成实测。
  6. 《Apache Xalan-J 2.7.3 配置参数详解》——参数矩阵实测。
  7. 《Apache Xalan-J 命令行工具详解》——Process/Compile/Transform 逐参数实测。