XSLT 教程(从入门到实战,中文版)
XSLT(Extensible Stylesheet Language Transformations)是将 XML 文档转换成其他格式(如 HTML、XML、纯文本、JSON 等)的强大语言。它属于 XSL 家族的一部分,常与 XPath 一起使用。
1. XSLT 基础概念
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 这里写转换规则 -->
</xsl:stylesheet>
- 所有 XSLT 元素都必须放在
<xsl:stylesheet>(或<xsl:transform>,两者等价)根元素中 - 命名空间必须声明:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - 目前最常用的是 XSLT 1.0 和 XSLT 2.0,XSLT 3.0 正在流行(Saxon 处理器支持)
2. 第一个“Hello World”例子
输入 XML(books.xml)
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="books.xsl"?>
<library>
<book id="1">
<title>平凡的世界</title>
<author>路遥</author>
<price>59.00</price>
</book>
<book id="2">
<title>围城</title>
<author>钱钟书</author>
<price>32.00</price>
</book>
</library>
XSLT 文件(books.xsl)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 匹配文档根节点 -->
<xsl:template match="/">
<html>
<head>
<title>我的书单</title>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #333; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>图书馆书单</h1>
<table>
<tr>
<th>ID</th>
<th>书名</th>
<th>作者</th>
<th>价格</th>
</tr>
<!-- 应用模板到每个 book 节点 -->
<xsl:apply-templates select="library/book"/>
</table>
</body>
</html>
</xsl:template>
<!-- 匹配每个 book 元素 -->
<xsl:template match="book">
<tr>
<td><xsl:value-of select="@id"/></td>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="author"/></td>
<td>¥<xsl:value-of select="price"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
直接在浏览器打开 books.xml 就会看到转换后的 HTML 表格。
3. 核心指令速查
| 指令 | 作用 | 示例 |
|---|---|---|
<xsl:template match="..."> | 定义模板规则 | <xsl:template match="book"> |
<xsl:apply-templates select="..."/> | 应用模板(继续处理子节点) | <xsl:apply-templates select="book"/> |
<xsl:value-of select="..."/> | 取出节点文本值 | <xsl:value-of select="title"/> |
<xsl:for-each select="..."> | 循环(不推荐多用,apply-templates 更佳) | <xsl:for-each select="book"> |
<xsl:if test="..."> | 条件判断 | <xsl:if test="price > 50">贵</xsl:if> |
<xsl:choose> | 多条件分支(switch) | 类似 if-elseif-else |
<xsl:sort> | 排序 | <xsl:sort select="price" order="descending"/> |
<xsl:variable> | 定义变量 | <xsl:variable name="tax" select="0.17"/> |
4. 常用 XPath 表达式(XSLT 离不开 XPath)
| 表达式 | 含义 |
|---|---|
book | 当前节点下的所有 book 子元素 |
//book | 整个文档中所有 book |
book[1] | 第一个 book |
book[last()] | 最后一个 book |
book[@id] | 有 id 属性的 book |
book[price>50] | 价格大于 50 的书 |
@id | 当前节点的 id 属性 |
text() | 文本节点 |
normalize-space() | 去除前后空格和多余换行 |
5. 条件语句示例
<xsl:template match="book">
<tr>
<td><xsl:value-of select="title"/></td>
<td>
<xsl:choose>
<xsl:when test="price < 30">便宜</xsl:when>
<xsl:when test="price < 60">中等</xsl:when>
<xsl:otherwise>较贵</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:template>
注意:XSLT 中 < 要写成 <,> 写成 >
6. 内置模板(为什么有时候什么都不写也能输出文本)
XSLT 有以下默认规则:
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
所以如果你只写 <xsl:apply-templates/>,会把所有文本原样输出。
7. 常用处理器和工具
| 工具 | 特点 |
|---|---|
| 浏览器自带 | Chrome/Firefox/Edge(仅支持 XSLT 1.0) |
| Saxon(Java) | 支持 XSLT 1.0/2.0/3.0,最强大 |
| xsltproc(libxslt) | Linux/macOS 自带,C 语言实现 |
| XSLT Fiddle | 在线测试:https://xsltfiddle.liberty-development.net/ |
| Oxygen XML Editor | 专业 XML/XSLT 开发工具 |
8. XSLT 2.0+ 高级特性(Saxon 支持)
<!-- 分组 group-by(XSLT 2.0) -->
<xsl:for-each-group select="book" group-by="author">
<h2><xsl:value-of select="current-grouping-key()"/></h2>
<ul>
<xsl:for-each select="current-group()">
<li><xsl:value-of select="title"/></li>
</xsl:for-each>
</ul>
</xsl:for-each-group>
<!-- 正则替换 replace() -->
<xsl:value-of select="replace(title, '世界', '地球')"/>
<!-- 格式化数字 format-number -->
<xsl:value-of select="format-number(price, '¥#,##0.00')"/>
9. 实战:XML 转 JSON(XSLT 3.0)
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
{
"books": [
<xsl:for-each select="library/book">
{
"id": "<xsl:value-of select="@id"/>",
"title": "<xsl:value-of select="title"/>",
"author": "<xsl:value-of select="author"/>",
"price": <xsl:value-of select="price"/>
}<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
]
}
</xsl:template>
</xsl:stylesheet>
10. 学习资源推荐
- W3Schools XSLT 教程(中文):https://www.w3schools.cn/xslt/
- 《XSLT 2.0 和 XPath 2.0 程序员参考手册》第 4 版(经典书籍)
- 在线练习:https://xsltfiddle.liberty-development.net/
- Saxon 官方文档:https://www.saxonica.com/documentation12/
动手练习是掌握 XSLT 的唯一途径!建议找一些真实的 XML 数据(RSS、OpenAPI 的 XML 版本、Maven pom.xml 等)来练习转换。
如果你有具体的 XML 和想要转换的目标格式(HTML、JSON、CSV 等),可以贴出来,我帮你写对应的 XSLT 模板!