XSLT 概述
本章定位 :理解 XSL 家族(XSLT/XSL-FO/XPath)的关系,掌握 XSLT 的"源树→结果树"转换处理模型和 XSLT 处理器的工作流程。
定义与作用
XSLT (eXtensible Stylesheet Language Transformations)是一种将 XML 文档 转换 为其他格式的语言。它可以把一份 XML 数据变成 HTML 网页、纯文本报告、另一个结构的 XML,甚至 CSV/JSON。
XSL(eXtensible Stylesheet Language)家族包含三个成员:
- XSLT :转换(transformation)——数据变形
- XPath :定位(selection)——数据选择
- XSL-FO :格式化对象(formatting objects)——页面布局(主要用于 PDF 打印)
三者关系:XSLT 用 XPath 选择源 XML 中的节点,按模板规则生成结果树,结果树可以是 HTML、文本或格式化对象(FO)。
核心原理:XSLT 转换处理模型
图解释 :XSLT 处理器读取源 XML 和 XSLT 样式表。从匹配 / 的根模板开始,通过 xsl:apply-templates 递归地将处理权传递给子节点。每个节点由其对应模板负责转换为结果树片段。
语法/结构要点
XSLT 样式表基本结构
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="/">
<!-- 根模板 -->
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="book">
<!-- 匹配 book 的模板 -->
</xsl:template>
</xsl:stylesheet>
核心概念
| 概念 | 作用 | 类比 |
|---|---|---|
xsl:stylesheet | 根元素,声明 XSLT 命名空间 | CSS 的 <style> |
xsl:template | 定义匹配特定节点的转换规则 | CSS 的选择器 + 规则块 |
match | 用 XPath 选择要处理的节点 | CSS 选择器 |
xsl:apply-templates | 递归传递处理权 | 函数递归调用 |
xsl:output | 指定输出格式(html/xml/text) | HTTP Content-Type |
完整示例:白歌用 XSLT 生成图书目录网页
场景说明
飞翔科技的架构师 白歌 要为公司内网生成一个图书目录网页。数据源是一个 XML 文件,她写一个 XSLT 样式表来自动生成 HTML。
操作前:裸 XML
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
</bookstore>
操作后:XSLT 样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="/">
<html>
<head>
<title>飞翔科技图书目录</title>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
th { background-color: #04AA6D; color: white; }
</style>
</head>
<body>
<h1>飞翔科技图书目录</h1>
<table>
<tr>
<th>书名</th><th>作者</th><th>年份</th><th>价格</th>
</tr>
<xsl:apply-templates select="bookstore/book"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="book">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="author"/></td>
<td><xsl:value-of select="year"/></td>
<td><xsl:value-of select="price"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
操作结果
浏览器加载 XML 时,通过 <?xml-stylesheet type="text/xsl" href="bookstore.xsl"?> 处理指令加载 XSLT,将 XML 源转换为带样式的 HTML 表格。转换后的 HTML 源码:
<html>
<head>
<title>飞翔科技图书目录</title>
<style>...</style>
</head>
<body>
<h1>飞翔科技图书目录</h1>
<table>
<tr><th>书名</th><th>作者</th><th>年份</th><th>价格</th></tr>
<tr><td>Learning XML</td><td>Erik T. Ray</td><td>2003</td><td>39.95</td></tr>
<tr><td>Everyday Italian</td><td>Giada De Laurentiis</td><td>2005</td><td>30.00</td></tr>
</table>
</body>
</html>
易错场景
错误一:忘记 xsl:apply-templates
<xsl:template match="/">
<html><body>
<!-- ❌ 没有 apply-templates,什么都不输出 -->
</body></html>
</xsl:template>
根模板必须包含 xsl:apply-templates 才能将处理权传递给子节点。
错误二:match 模式不匹配目标
<!-- ❌ book 不是 / 的直接子元素 -->
<xsl:template match="book">
<!-- ✅ 写正确的路径 -->
<xsl:template match="bookstore/book">
<!-- 或依赖 apply-templates 传递 -->
面试考点
| 考点 | 参考答案要点 |
|---|---|
| XSL 家族包含哪三个成员? | XSLT(转换)、XPath(定位)、XSL-FO(格式化对象)。XSLT 用 XPath 选节点,结果可以是 FO 用于打印 |
| XSLT 的"推"模型如何工作? | 从匹配 / 的根模板开始,逐层 xsl:apply-templates 将处理权推给子节点,每个节点由对应模板处理。这是声明式递归处理 |
| XSLT 和 CSS 的本质区别? | CSS 只改变呈现样式,不改变文档结构;XSLT 可以完全重组文档——增删节点、排序、生成新结构 |