Apache Xalan 配置参数详解

详解 Apache Xalan-J 2.7.3 配置:Process 命令行参数逐项与实测回显、Transformer 输出属性、XSLTC 编译器选项、JAXP 系统属性切换与 JVM 堆设置,附常见问题与官方参考链接。

Apache XalanApache Xalan2026/10/12

Apache Xalan 配置参数详解

目标:系统梳理 Apache Xalan-J 2.7.3 的全部配置入口——命令行 org.apache.xalan.xslt.Process 参数、XSLTC 独立编译器选项、Transformer/JAXP 编程接口属性、JAXP 系统属性与 JVM 参数。文中标注"实测"的条目均已在 Ubuntu 22.04.5 + OpenJDK 17.0.20.1 与 CentOS 8.5.2111 + OpenJDK 17.0.1 双环境验证,回显为真实输出。

一、配置总览与实测环境

Xalan-J 没有服务进程与全局配置文件,配置分布在四个层面:

层面入口典型用途
命令行org.apache.xalan.xslt.Process 参数、org.apache.xalan.xsltc.cmdline.Compile 选项一次性转换、CI 脚本
编程接口Transformer.setOutputProperty、TransformerFactory.setAttribute/setFeature/setErrorListener应用内嵌转换
JVM/系统属性-Djavax.xml.transform.TransformerFactory、-Xms/-Xmx、MAVEN_OPTS工厂切换、内存
服务声明xalan.jar 内 META-INF/services/javax.xml.transform.TransformerFactoryclasspath 默认工厂

实测环境:

项目环境 A环境 B
操作系统Ubuntu 22.04.5 LTSCentOS Linux 8.5.2111
JDKOpenJDK 17.0.20.1OpenJDK 17.0.1
Maven3.6.33.5.4
Xalan-Jxalan:xalan:2.7.3 + serializer:2.7.3同左

二、Process 命令行参数逐项详解

执行 java -cp <xalan.jar>:<serializer.jar> org.apache.xalan.xslt.Process(无参数)输出分两页帮助(第二页需按回车),完整文本沉淀见《Apache Xalan 常用 CLI 命令与工具详解》第四节。参数分三组:通用、解释型专用、XSLTC 专用。

2.1 通用输入输出参数

参数说明
-IN inputXMLURL输入 XML 文档的 URL 或路径
-XSL XSLTransformationURL样式表 URL;省略时按 -MEDIA 或文档内 xml-stylesheet 处理指令查找关联样式表
-OUT outputFileName输出文件;目录必须预先存在,实测目录缺失直接报 XSLT Error (java.io.FileNotFoundException): out/cli.html (No such file or directory)
-XML强制使用 XML 输出器并写 XML 声明
-HTML强制使用 HTML 输出器
-TEXT强制使用纯文本输出器
-E不展开实体引用
-EDUMP {可选文件名}出错时转储堆栈;实测给文件名时生成转储文件,内容为错误收尾路径的异常堆栈

三个格式化开关实测对比(同一样式表 xsl:output method="html"):

  • 默认/-HTML:输出 <META http-equiv="Content-Type" content="text/html; charset=UTF-8">,无 XML 声明;
  • -XML:实测输出以 <?xml version="1.0" encoding="UTF-8"?><html> 开头;
  • -TEXT:配合 method="text" 样式表输出纯文本行,实测:
Java 核心技术 | 张三 | 99.50
MySQL 调优实战 | 李四 | 79.00
Java 并发编程 | 王五 | 89.90
TCP/IP 详解 | 赵六 | 128.00

2.2 参数传递与诊断

参数说明
-PARAM name expression设置样式表顶层 xsl:param。值按 XPath 表达式处理,实测直接传单词(如 Java)按字符串生效;传中文在 UTF-8 locale 下正常(需 LANG=C.UTF-8,实测 POSIX locale 下乱码并导致匹配数错误)
-MEDIA mediaType按 xml-stylesheet 处理指令的 media 属性选择关联样式表
-FLAVOR flavorName显式指定执行模型:s2s(SAX2SAX 流式)或 d2d(DOM2DOM);实测 -FLAVOR d2d 与默认结果一致
-DIAG打印总耗时;实测回显 --------- Transform of data/books.xml via data/books.xsl took 203 ms

-PARAM 实测示例:

java -cp $CP org.apache.xalan.xslt.Process -IN data/books.xml -XSL data/books.xsl \
     -PARAM keyword Java -OUT out/cli-java.html
grep -o "共 [0-9]* 本匹配" out/cli-java.html

✅ 实测回显:

共 2 本匹配

2.3 解析器与安全扩展

参数说明
-URIRESOLVER 全类名指定实现 javax.xml.transform.URIResolver 的类,解析 document()/xsl:import 等 URI
-ENTITYRESOLVER 全类名指定实现 org.xml.sax.EntityResolver 的类,接管实体解析
-CONTENTHANDLER 全类名指定自定义 ContentHandler 接收序列化输出
-SECURE开启 secure processing:限制扩展函数、document() 访问等,防外部资源滥用

2.4 解释型引擎专用参数(不带 -XSLTC 时生效)

参数说明
-QC安静模式,抑制模板匹配冲突告警
-TT跟踪模板被调用的事件
-TG跟踪每个生成(generation)事件
-TS跟踪每次节点选择(selection)事件
-TTC跟踪模板子节点处理事件
-TCLASS 类名指定自定义 TraceListener 扩展类
-L为源文档行号跟踪(错误定位更精确)
-INCREMENTAL开启增量 DTM 构造(http://xml.apache.org/xalan/features/incremental),适合提前输出场景
-NOOPTIMIMIZE关闭样式表优化(http://xml.apache.org/xalan/features/optimize=false),排查优化器问题时用
-RL 深度限制样式表递归深度,防止失控递归耗尽内存

2.5 XSLTC 引擎专用参数

先加 -XSLTC 切换编译型引擎,再配以下参数:

参数说明
-XSLTC本次转换改用 XSLTC 引擎(先编译为 translet 再执行);实测 -XSLTC -IN ... -XSL ... -OUT ... 输出与解释型一致
-XO [transletName]指定生成的 translet 类名
-XD 目录translet 输出目录
-XJ jarfile把 translet 类打包进指定 jar
-XP 包名为所有生成的 translet 类加包名前缀
-XN开启模板内联(template inlining)
-XX额外调试信息输出
-XT若可行则直接用已有 translet 转换

三、Transformer 编程接口属性

3.1 输出属性(OutputKeys)

通过 transformer.setOutputProperty(key, value) 设置,与 XSLT xsl:output 等价:

属性常量取值示例说明
OutputKeys.METHODxml / html / text输出方法
OutputKeys.ENCODINGUTF-8输出编码
OutputKeys.INDENTyes / no是否缩进
OutputKeys.OMIT_XML_DECLARATIONyes / no是否省略 XML 声明
OutputKeys.VERSION1.0输出版本
OutputKeys.STANDALONEyes / nostandalone 声明
OutputKeys.DOCTYPE_PUBLIC / DOCTYPE_SYSTEM公共/系统标识生成 DOCTYPE
OutputKeys.CDATA_SECTION_ELEMENTS元素名列表指定元素文本按 CDATA 输出
OutputKeys.MEDIA_TYPEtext/html输出 MIME 类型

实测片段(见《Apache Xalan 快速入门与集成示例》):

transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

实测输出(HTML 头部):

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">

3.2 参数与引擎特征

// 外部参数:对应样式表顶层 xsl:param
transformer.setParameter("keyword", "Java");

// 工厂特征:安全处理(等价命令行 -SECURE)
factory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);

// 解释型引擎特征(setAttribute,URI 即特性名)
factory.setAttribute("http://xml.apache.org/xalan/features/incremental", Boolean.TRUE);
factory.setAttribute("http://xml.apache.org/xalan/features/optimize", Boolean.FALSE);

3.3 错误监听

TransformerFactory.setErrorListener 管样式表编译期错误,Transformer.setErrorListener 管转换期错误。实测自定义监听器对不合法样式表输出:

[样式表致命错误] org.xml.sax.SAXParseException; systemId: file:/opt/xalan-demo/data/books-bad.xsl; lineNumber: 6; columnNumber: 5; The element type "xsl:if" must be terminated by the matching end-tag "</xsl:if>".
捕获 TransformerException: javax.xml.transform.TransformerException: org.xml.sax.SAXParseException; ...
EXIT=1

四、XSLTC 独立编译器选项

工具类:org.apache.xalan.xsltc.cmdline.Compile(实测自报 XSLTC version 1.4)。无参数运行输出用法:

SYNOPSIS
  java org.apache.xalan.xsltc.cmdline.Compile [-o <output>]
     [-d <directory>] [-j <jarfile>] [-p <package>]
     [-n] [-x] [-u] [-v] [-h] { <stylesheet> | -i }
选项说明
-o <output>生成的 translet 类名(编译多个样式表时忽略)
-d <directory>translet 输出目录(目录须已存在)
-j <jarfile>把 translet 类打包为 jar
-p <package>translet 类的包名前缀
-n启用模板内联(官方说明默认行为平均更优)
-x额外调试输出
-u把样式表参数当 URL 解析
-i从 stdin 读样式表
-v打印编译器版本(实测 XSLTC version 1.4)
-h帮助

编译与运行实测:

java -cp $CP org.apache.xalan.xsltc.cmdline.Compile -o BooksTranslet -d out/translet data/books.xsl
ls out/translet/

✅ 实测回显:

BooksTranslet$0.class
BooksTranslet$1.class
BooksTranslet$2.class
BooksTranslet.class

运行编译好的 translet(注意实测 2.7.3 的参数顺序为 XML 在前、translet 类名在后):

java -cp "out/translet:$CP" org.apache.xalan.xsltc.cmdline.Transform data/books.xml BooksTranslet

✅ 实测回显(stdout,截取头部):

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">

五、JAXP 系统属性与 JVM 参数

5.1 工厂选择属性 javax.xml.transform.TransformerFactory

四种场景实测回显(TransformerFactory.newInstance().getClass().getName()):

场景实测结果
classpath 无 xalan.jarcom.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl(JDK 内置)
classpath 有 xalan.jar(默认)org.apache.xalan.processor.TransformerFactoryImpl(解释型,来自 jar 内服务文件)
-Djavax.xml.transform.TransformerFactory=org.apache.xalan.xsltc.trax.TransformerFactoryImplorg.apache.xalan.xsltc.trax.TransformerFactoryImpl(XSLTC 编译型)
-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImplorg.apache.xalan.processor.TransformerFactoryImpl(解释型,显式)

优先级:JVM 系统属性 > $JAVA_HOME/conf/jaxp.properties(JDK 9+,JDK 8 位于 $JAVA_HOME/lib/jaxp.properties)> classpath 服务声明 > JDK 平台默认。OpenJDK 17 下实测以上四种组合全部正常工作,无需 --add-opens。

5.2 JVM 堆参数(-Xms/-Xmx)

  • mvn 构建进程:MAVEN_OPTS(可放环境变量、/etc/profile.d/maven.sh 或 ~/.mavenrc);
  • 命令行 java 进程(Process/XSLTC):直接写 java -Xms256m -Xmx512m ...,不读取 MAVEN_OPTS/JAVA_OPTS(这两个变量只被 mvn、Tomcat 等包装脚本消费);
  • 应用内嵌:在应用启动脚本里给 java 命令加 -Xms256m -Xmx512m。

XSLTC 编译大样式表、转换大文档建议 256~512MB:

MAVEN_OPTS="-Xms256m -Xmx512m" mvn -B clean package
java -Xms256m -Xmx512m -cp $CP org.apache.xalan.xslt.Process -XSLTC -IN data/big.xml -XSL data/books.xsl -OUT out/big.html

实测验证回显(进程保持存活期间抓取):

ps -ef | grep [j]ava

✅ Ubuntu 22.04 实测(Maven 构建进程,截取关键段):

java -Xms256m -Xmx512m -classpath /usr/share/maven/boot/plexus-classworlds-2.x.jar -Dclassworlds.conf=/usr/share/maven/bin/m2.conf -Dmaven.home=/usr/share/maven -Dlibrary.jansi.path=/usr/share/maven/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/opt/xalan-demo org.codehaus.plexus.classworlds.launcher.Launcher -B clean package
jps -v

✅ 实测(Ubuntu:6757 MemoryDemo -Xms256m -Xmx512m;CentOS 8:1149 MemoryDemo -Xms256m -Xmx512m)

6757 MemoryDemo -Xms256m -Xmx512m

程序内核验:Runtime.getRuntime().maxMemory() 实测打印 JVM 最大堆(maxMemory): 512 MB。

六、常见问题

Q1: 加了 -Djavax.xml.transform.TransformerFactory 却仍拿到 JDK 内置实现?

答:确认 -D 在 java 命令与主类之间(不是命令尾部);确认运行环境是同一个 JVM;JAXP 属性优先级最高,若仍无效说明 classpath 与 -cp 不一致。

Q2: -PARAM 传中文乱码、匹配数错误?

答:系统 locale 不是 UTF-8。export LANG=C.UTF-8 后重跑;Java 程序 stdout 中文变问号同理。实测该问题在 Ubuntu 22.04 与 CentOS 8.5 缺省 locale 下均会出现。

Q3: -OUT 报 FileNotFoundException 但文件明明可写?

答:是父目录不存在。Process 不会自动建目录,先 mkdir -p out。

Q4: cmdline.Compile 生成的 translet 运行时报 Cannot find class '<XML 路径>'?

答:实测 2.7.3 的 cmdline.Transform 生效参数顺序是 XML 文档在前、translet 类名在后;另外它失败时退出码仍为 0,脚本需检查输出内容而非退出码。

Q5: -EDUMP 生成的转储里是 NPE 而不是样式表错误?

答:实测样式表 XML 不合法时,Process 先在 stderr 打印 [Fatal Error] ... SAXParseException(真正原因,看它);-EDUMP 文件记录的是错误收尾路径的二次 RuntimeException("format" is null),仅供辅助。

Q6: 只想换输出编码,命令行怎么传?

答:命令行编码由样式表 <xsl:output encoding="UTF-8"/> 决定;编程接口用 setOutputProperty(OutputKeys.ENCODING, "UTF-8")。XML 源/样式表自身的解析编码由其 XML 声明决定,与系统 locale 无关(实测 POSIX locale 下读 UTF-8 的 XML/XSL 输出中文正常)。

七、参考链接