XSLT 到底能不能“编辑”XML?—— 2025 年最完整答案
一句话结论:
XSLT 本身不能“就地修改(in-place edit)”一个 XML 文件,
但它却是目前最强大、最标准、最安全的 XML“编辑/转换/生成”工具。
下面按真实需求给你分类讲解怎么用 XSLT “编辑”XML。
1. XSLT 真正能做的事(99% 的“编辑”需求其实是这些)
| 需求 | 用 XSLT 怎么做 | 推荐工具 / 处理器 |
|---|---|---|
| 添加节点 / 属性 | 身份模板 + / | Saxon / Xalan / libxslt |
| 删除节点 / 属性 | 身份模板 + 不复制该节点 | 所有处理器 |
| 修改节点内容或属性值 | 身份模板 + 重写 | 所有处理器 |
| 改节点名(rename) | 所有处理器 | |
| 移动节点位置 | 调整 的顺序 | 所有处理器 |
| 批量替换、条件修改 | 、、参数 + 匹配模板 | 所有处理器 |
| 拆分一个 XML 成多个文件 | XSLT 3.0 + | Saxon 10+ / SaxonJS / EXPath |
| 合并多个 XML | (XSLT 3.0)或 document() 函数 | Saxon 10+ |
| 按条件增删改(类似 JSON Patch) | 完全可以实现 | Saxon 10+ |
2. 最经典的“身份模板”(Identity Template)—— 万能编辑起点
<!-- edit.xsl -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 1. 复制一切(身份模板) -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- 2. 在这里写你真正的“编辑”规则,优先级更高 -->
<!-- 示例① 删除所有 <price> 节点 -->
<xsl:template match="price"/>
<!-- 示例② 把所有 book 的 status 属性改成 "published" -->
<xsl:template match="book/@status">
<xsl:attribute name="status">published</xsl:attribute>
</xsl:template>
<!-- 示例③ 在根节点下添加一个 <last-updated>2025-11-26</last-updated> -->
<xsl:template match="/library">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<last-updated>2025-11-26</last-updated>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
运行命令(任选其一):
# XSLT 1.0/2.0(最通用)
java -jar saxon-he-12.5.jar -s:books.xml -xsl:edit.xsl -o:books-new.xml
# XSLT 3.0(支持拆分多个文件)
java -jar saxon-ee-12.5.jar -s:input.xml -xsl:split.xsl
# Windows + xsltproc
xsltproc edit.xsl books.xml > books-new.xml
# Python 一行搞定
python -c "import lxml.etree as ET; t=ET.XSLT(ET.parse('edit.xsl')); print(ET.tostring(t(ET.parse('books.xml')), pretty_print=True).decode())" > new.xml
3. XSLT 3.0 真正的“编辑神器”(2025 年强烈推荐)
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 把 price > 100 的书拆成 expensive-books.xml -->
<xsl:template match="book[price > 100]">
<xsl:result-document href="expensive/book-{@id}.xml">
<book>
<xsl:copy-of select="."/>
<edited-by>XSLT-3.0</edited-by>
</book>
</xsl:result-document>
</xsl:template>
<!-- 其余照抄 -->
<xsl:template match="@*|node()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
4. 真实世界“编辑 XML”最常用 8 个模板(直接复制粘贴)
<!-- 1. 改属性值 -->
<xsl:template match="book/@isbn">
<xsl:attribute name="isbn">
<xsl:value-of select="translate(., '-', '')"/> <!-- 去掉横线 -->
</xsl:attribute>
</xsl:template>
<!-- 2. 改节点名 book → item -->
<xsl:template match="book">
<item>
<xsl:apply-templates select="@*|node()"/>
</item>
</xsl:template>
<!-- 3. 批量加前缀 -->
<xsl:template match="title">
<title>[新书]<xsl:value-of select="."/></title>
</xsl:template>
<!-- 4. 按条件删除 -->
<xsl:template match="book[year < 2000]"/> <!-- 删除 2000 年前的老书 -->
<!-- 5. 排序后再输出 -->
<xsl:template match="library">
<library>
<xsl:apply-templates select="book">
<xsl:sort select="author"/>
<xsl:sort select="title"/>
</xsl:apply-templates>
</library>
</xsl:template>
5. 不能用 XSLT 做的“编辑”场景(以及替代方案)
| 场景 | XSLT 能不能做? | 推荐替代工具 |
|---|---|---|
| 就地修改文件(不生成新文件) | 不能 | Python lxml、Java DOM、xmllint |
| 超大文件(> 5GB)逐行编辑 | 难(内存爆炸) | Saxon-EE 流式 + XMLStreamReader |
| 需要事务、回滚 | 不能 | 数据库(BaseX、eXist-db) |
| 频繁随机修改 | 性能差 | 用 JSON 代替,或 XQuery Update |
6. 终极结论(2025 年)
| 你想做什么 | 最佳工具选择 |
|---|---|
| 批量、规则化、安全地编辑 XML | XSLT(尤其是 3.0 + Saxon) |
| 偶尔手动改几个节点 | Oxygen XML Editor / VS Code |
| 超大文件、流式处理 | Saxon-EE 12 + 流式模板 |
| 需要事务、版本控制 | 原生 XML 数据库(BaseX) |
所以:XSLT 不是不能“编辑”XML,而是编辑 XML 的最优雅、最标准、最强大的方式——只是它永远会生成一个新文件,而不是修改原文件。
需要我直接给你写一个“万能 XML 编辑器”XSL 模板(支持命令行传参增删改)吗?告诉我你的 XML 结构,我 30 秒出代码。