xslt任务是ant内置核心任务,无需额外下载,但默认引擎性能差、兼容性弱;需注意依赖检测缺失、内存泄漏及引擎切换等问题。

xslt 任务在 Ant 中是处理 XML 转换的核心内置任务,不是插件,不用额外下载(JDK 1.4+ 自带),但默认用的是老版本 XSLT 引擎(如 JAXP 默认的 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl),性能和标准支持有限——**能跑通不代表没坑,尤其遇到 document()、collection() 或大文件时容易崩或行为异常。**
基础用法:单样式表批量转换
最常见场景:把 src/xml/ 下所有 .xml 文件,用 style.xsl 转成 HTML 放到 build/html/。
<xslt basedir="src/xml" destdir="build/html" style="style.xsl" includes="**/*.xml" extension=".html"/>
-
basedir是源 XML 的根目录(不是样式表所在目录);style是相对于 projectbasedir的路径,不是相对于basedir -
includes和excludes支持 Ant 风格通配符(**/*.xml、pages/*.xml),不支持正则 -
extension仅当没嵌套<mapper></mapper>时生效;若用了<mapper type="glob" from="*.xml" to="*.html"></mapper>,它会被忽略 - 别用
in/out做单文件转换再覆盖原文件——Ant 会报错“source and destination are the same”,必须用临时文件中转
依赖外部 XML(比如 snippets.xml)时怎么触发重构建?
Ant xslt 本身不自动检测 document('snippets.xml') 这类引用文件是否变更,所以即使 snippets.xml 改了,也不会重新生成目标文件。
- 必须显式把依赖文件加进
<depends></depends>或用<uptodate></uptodate>手动判断,例如: - 在
<xslt></xslt>外层加<uptodate property="xslt.up.to.date"><srcfiles dir="." includes="pages/*.xml,snippets.xml"></srcfiles><targetfiles dir="build" includes="**/*.html"></targetfiles></uptodate> - 然后
<target name="transform" unless="xslt.up.to.date"></target>包裹<xslt></xslt> - 否则每次都要靠
force="true"硬刷,浪费时间
内存爆掉?大文件或多个文件连续转换时必看
处理 >200MB XML 或循环跑几十个文件时,Java 堆内存会持续上涨,最终 java.lang.OutOfMemoryError: Java heap space ——这不是 bug,是 Ant 默认复用 Transformer 实例导致的资源未释放。
- 加
reloadstylesheet="true"(Ant 1.5.2+),让每次转换都重建Transformer,代价是启动稍慢,但内存可控 - 避免用
trax+ 内置 Xalan(已废弃);推荐显式指定 Saxon:processor="trax" classpathref="saxon.classpath",并确保saxon-he.jar在 classpath - 对超大单文件(如 1.9GB),先用
<splitxml></splitxml>类任务拆分,再并行转换;别指望一个<xslt></xslt>吃下全部
动态选样式表?不能直接 for-each,得绕道
Ant 没有原生循环,无法对 styles/*.xsl 里的每个 XSL 文件执行一次转换。硬要实现,只能用 <antcall></antcall> + 属性传递,或者用 <foreach></foreach>(需 ant-contrib)。
- 简单方案:用 Shell/Python 先生成一堆 target,再
ant target1 target2 ... - 工程方案:用
<scriptdef></scriptdef>写 Groovy 脚本遍历styles目录,动态调用project.createTask("xslt") - 别写
style="${style.name}"然后指望 Ant 替换——属性展开发生在 task 初始化前,<xslt></xslt>不支持运行时绑定样式表路径
真正麻烦的从来不是语法对不对,而是 XSLT 引擎差异(Saxon vs Xalan vs JDK 内置)、URI 解析失败(xmlcatalog 配不全就找不到 DTD)、以及 Ant 对“依赖”这件事的天然迟钝——它只认文件时间戳,不管 document() 里写了啥。








