XML擅长存储和传输结构化数据,但它本身没有任何展示能力。如果要把一份XML文档以表格、列表等友好的形式呈现给用户,最经典的做法就是使用XSLT(Extensible Stylesheet Language Transformations)作为桥梁,把XML转换成HTML。XSLT本质上也是一种XML,它通过模板规则描述如何把源文档中的节点映射为目标文档中的内容。下面先给出一个最简单的场景:一份保存图书信息的XML文件。

一、准备XML数据源与XSLT样式表
假设我们有一个名为books.xml的文件,里面保存了几本书的书名、作者和价格。数据结构非常简单,根节点是bookstore,下面包含多个book子节点,每个book节点再用子元素描述具体信息。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title>深入理解Java虚拟机</title>
<author>周志明</author>
<price>79.00</price>
</book>
<book>
<title>JavaScript高级程序设计</title>
<author>Matt Frisbie</author>
<price>129.00</price>
</book>
<book>
<title>Linux命令行与Shell脚本</title>
<author>Richard Blum</author>
<price>89.00</price>
</book>
</bookstore>接下来编写XSLT样式表books.xsl。样式表同样以XML声明开头,根元素是xsl:stylesheet,其中version属性声明使用的XSLT版本,1.0版本的兼容性最好,几乎所有环境都支持。xsl:output元素非常关键,它告诉处理器输出的文档类型是html,编码为UTF-8,并做适当缩进。
整个转换的核心思想是模板匹配:xsl:template的match属性使用XPath表达式定位到源文档的节点,模板体中则书写目标HTML结构。xsl:for-each相当于循环语句,会遍历所有book节点;xsl:value-of负责取出某个节点的文本值插入到输出中;xsl:sort可以对结果排序,select指定排序依据,data-type设为number表示按数值排序而不是字符串排序。
<?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" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>图书列表</title>
<style>
table { border-collapse: collapse; width: 60%; margin: 30px auto; }
th, td { border: 1px solid #999; padding: 8px 12px; text-align: left; }
th { background: #4a90d9; color: #fff; }
tr:nth-child(even) { background: #f2f2f2; }
</style>
</head>
<body>
<h2 style="text-align:center;">馆藏图书清单</h2>
<table>
<tr>
<th>书名</th>
<th>作者</th>
<th>价格(元)</th>
</tr>
<xsl:for-each select="bookstore/book">
<xsl:sort select="price" data-type="number" order="descending"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="author"/></td>
<td><xsl:value-of select="price"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>二、浏览器端自动转换的写法
最省事的转换方式是让浏览器替你完成。主流浏览器都内置了XSLT处理器,只要在XML文件中通过xml-stylesheet处理指令关联样式表,浏览器打开该XML时就会自动应用转换并渲染出HTML页面。注意这行指令必须写在XML声明之后、根元素之前。
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="books.xsl"?> <bookstore> <!-- 后续节点内容不变 --> </bookstore>
这种方式的好处是零代码、零依赖,特别适合静态数据的快速展示,比如配置导出、接口调试结果的预览等场景。不过它也有明显的局限:转换完全依赖客户端能力,如果目标用户的浏览器不支持XSLT或者样式表路径加载失败,页面就会显示原始XML甚至报错。另外,出于安全策略,部分浏览器在本地直接打开文件时会限制加载本地XSLT文件,此时需要通过HTTP服务器访问才能正常转换。因此在生产环境中,更推荐的做法是在服务端完成转换,把生成好的HTML直接输出给客户端,这样兼容性和性能都更有保障。
三、使用Java和Python在服务端完成转换
服务端转换可以把XSLT当作数据处理流水线的一环,转换结果既可以写入文件,也可以直接作为HTTP响应返回。Java从标准库中就提供了Transformer工厂类,无需引入任何第三方依赖。下面的示例读取books.xml和books.xsl,完成转换后把HTML保存到output.html。
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.FileOutputStream;
public class XsltDemo {
public static void main(String[] args) throws Exception {
// 创建转换器工厂并生成转换器实例
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource("books.xsl"));
// 执行转换:源为XML文件,结果写入HTML文件
transformer.transform(
new StreamSource("books.xml"),
new StreamResult(new FileOutputStream("output.html")));
System.out.println("转换完成,结果已写入 output.html");
}
}Python方面,标准库自带的ElementTree只能解析XML,不包含XSLT引擎,因此需要借助功能完善的lxml库。lxml基于C语言实现,性能出色,API也很简洁,通过etree.XSLT类即可完成转换。
from lxml import etree
# 解析XML数据源和XSLT样式表
xml_doc = etree.parse("books.xml")
xslt_doc = etree.parse("books.xsl")
# 创建转换对象并执行转换
transform = etree.XSLT(xslt_doc)
result = transform(xml_doc)
# 将结果以字符串和文件两种形式输出
print(str(result))
result.write_output("output.html", encoding="UTF-8")两段代码的核心流程完全一致:加载XML源文档、加载样式表、创建转换器、执行转换、输出结果。掌握这个流程后,你可以把XSLT应用到更复杂的场景,例如把系统导出的报表XML转换成带样式的对账单,或者在内容管理系统中将结构化内容渲染为不同的页面模板。XSLT在数据格式转换领域虽然不如现代模板引擎流行,但它声明式的处理方式和跨平台的标准化特性,让它在需要标准化、可移植转换逻辑的场合依然有不可替代的价值。