XSLT 转换:XML 样式表语言实战指南与丰富代码示例

发布时间:2026/9/2 8:20:36
XSLT 转换:XML 样式表语言实战指南与丰富代码示例 1. XSLT 概述什么是 XSLTXSLTExtensible Stylesheet Language Transformations是一种用于将 XML 文档转换为其他格式如 HTML、XML、纯文本的语言。它是 W3C 标准属于 XSL可扩展样式表语言家族的一部分。XSLT 的核心思想是“声明式转换”——你定义一组规则模板告诉处理器如何匹配和处理源 XML 中的节点从而生成新的输出树。XSLT 处理器如浏览器内置的 XSLT 引擎、Java 中的 Saxon、.NET 中的 XslCompiledTransform读取 XML 源文档和 XSLT 样式表然后应用转换规则最终输出目标文档。2. 基础语法与结构一个典型的 XSLT 样式表以 XML 格式编写根元素为xsl:stylesheet或xsl:transform。以下是一个最简单的 XSLT 示例它将一个简单的 XML 转换为 HTML2.1 源 XML (source.xml)?xml version1.0 encodingUTF-8? bookstore book category编程 titleJava 核心技术/title authorCay S. Horstmann/author price89.90/price /book book category小说 title三体/title author刘慈欣/author price45.00/price /book /bookstore2.2 XSLT 样式表 (transform.xsl)?xml version1.0 encodingUTF-8? xsl:stylesheet version1.0 xmlns:xslhttp://www.w3.org/1999/XSL/Transform !-- 匹配根节点输出 HTML 骨架 -- xsl:template match/ html head title书店书目/title /head body h1书店书目列表/h1 table border1 tr th书名/th th作者/th th价格/th th分类/th /tr !-- 对每个 book 元素应用模板 -- xsl:apply-templates selectbookstore/book/ /table /body /html /xsl:template !-- 匹配 book 元素输出表格行 -- xsl:template matchbook tr tdxsl:value-of selecttitle//td tdxsl:value-of selectauthor//td tdxsl:value-of selectprice//td tdxsl:value-of selectcategory//td /tr /xsl:template /xsl:stylesheet2.3 转换结果 (HTML)html head title书店书目/title /head body h1书店书目列表/h1 table border1 tr th书名/th th作者/th th价格/th th分类/th /tr tr tdJava 核心技术/td tdCay S. Horstmann/td td89.90/td td编程/td /tr tr td三体/td td刘慈欣/td td45.00/td td小说/td /tr /table /body /html3. 核心 XSLT 元素详解3.1 xsl:template 与 match 属性模板是 XSLT 的核心。xsl:template matchXPath表达式定义了当处理器遇到匹配该表达式的节点时要执行的操作。!-- 匹配所有 paragraph 元素 -- xsl:template matchparagraph pxsl:apply-templates//p /xsl:template !-- 匹配根节点 -- xsl:template match/ htmlxsl:apply-templates//html /xsl:template !-- 匹配带有特定属性的元素 -- xsl:template matchbook[category编程] div classprogramming-book xsl:apply-templates/ /div /xsl:template3.2 xsl:value-of 提取节点值用于提取节点或属性的文本内容。!-- 提取当前节点的 title 子元素的值 -- xsl:value-of selecttitle/ !-- 提取当前节点的 category 属性值 -- xsl:value-of selectcategory/ !-- 使用 XPath 函数 -- xsl:value-of selectconcat(author, - , price)/ xsl:value-of selectsum(book/price)/ !-- 求和 --3.3 xsl:apply-templates 与 xsl:for-eachxsl:apply-templates指示处理器继续处理当前节点的子节点或通过 select 选择的节点集。xsl:for-each则用于显式循环。!-- 使用 apply-templates更符合 XSLT 声明式风格 -- xsl:template matchcatalog ul xsl:apply-templates selectproduct/ /ul /xsl:template xsl:template matchproduct lixsl:value-of selectname//li /xsl:template !-- 使用 for-each过程式循环 -- xsl:template matchcatalog ul xsl:for-each selectproduct lixsl:value-of selectname//li /xsl:for-each /ul /xsl:template3.4 xsl:if 与 xsl:choose 条件判断!-- xsl:if -- xsl:template matchbook div xsl:if testprice 50 span classexpensive高价书/span /xsl:if xsl:value-of selecttitle/ /div /xsl:template !-- xsl:choose (类似 switch-case) -- xsl:template matchbook div xsl:choose xsl:when testcategory编程 img srccode-icon.png/ /xsl:when xsl:when testcategory小说 img srcnovel-icon.png/ /xsl:when xsl:otherwise img srcdefault-icon.png/ /xsl:otherwise /xsl:choose xsl:value-of selecttitle/ /div /xsl:template4. 进阶示例XML 到 XML 的转换XSLT 不仅限于生成 HTML它更常用于 XML 到 XML 的数据映射与重组。4.1 源 XML订单 (order.xml)?xml version1.0 encodingUTF-8? Order OrderIDORD-20240811-001/OrderID Customer Name张三/Name Emailzhangsanexample.com/Email /Customer Items Item SKUPROD-1001/SKU Name无线鼠标/Name Quantity2/Quantity UnitPrice89.50/UnitPrice /Item Item SKUPROD-1002/SKU Name机械键盘/Name Quantity1/Quantity UnitPrice399.00/UnitPrice /Item /Items /Order4.2 XSLT转换为简化的发货单 (invoice.xsl)?xml version1.0 encodingUTF-8? xsl:stylesheet version1.0 xmlns:xslhttp://www.w3.org/1999/XSL/Transform xsl:output methodxml indentyes/ xsl:template match/Order Invoice InvoiceNumber xsl:value-of selectOrderID/ /InvoiceNumber CustomerName xsl:value-of selectCustomer/Name/ /CustomerName TotalAmount xsl:value-of selectsum(Items/Item/(Quantity * UnitPrice))/ /TotalAmount LineItems xsl:for-each selectItems/Item LineItem ProductCodexsl:value-of selectSKU//ProductCode ProductNamexsl:value-of selectName//ProductName Qtyxsl:value-of selectQuantity//Qty Pricexsl:value-of selectUnitPrice//Price Subtotal xsl:value-of selectQuantity * UnitPrice/ /Subtotal /LineItem /xsl:for-each /LineItems /Invoice /xsl:template /xsl:stylesheet4.3 转换结果 XML?xml version1.0 encodingUTF-8? Invoice InvoiceNumberORD-20240811-001/InvoiceNumber CustomerName张三/CustomerName TotalAmount578.0/TotalAmount LineItems LineItem ProductCodePROD-1001/ProductCode ProductName无线鼠标/ProductName Qty2/Qty Price89.50/Price Subtotal179.0/Subtotal /LineItem LineItem ProductCodePROD-1002/ProductCode ProductName机械键盘/ProductName Qty1/Qty Price399.00/Price Subtotal399.0/Subtotal /LineItem /LineItems /Invoice5. 在编程语言中调用 XSLT5.1 Java 示例 (使用 javax.xml.transform)import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.io.*; public class XsltTransformerJava { public static void main(String[] args) throws TransformerException { // 源 XML、XSLT 样式表、输出文件 Source xmlSource new StreamSource(new File(source.xml)); Source xsltSource new StreamSource(new File(transform.xsl)); Result outputResult new StreamResult(new File(output.html)); // 创建转换器工厂和转换器 TransformerFactory factory TransformerFactory.newInstance(); Transformer transformer factory.newTransformer(xsltSource); // 设置输出属性可选 transformer.setOutputProperty(OutputKeys.INDENT, yes); transformer.setOutputProperty(OutputKeys.ENCODING, UTF-8); // 执行转换 transformer.transform(xmlSource, outputResult); System.out.println(XSLT 转换完成); } }5.2 C# (.NET) 示例 (使用 XslCompiledTransform)using System; using System.Xml; using System.Xml.Xsl; class XsltTransformerCSharp { static void Main() { // 创建 XslCompiledTransform 实例 XslCompiledTransform transformer new XslCompiledTransform(); // 加载 XSLT 样式表 transformer.Load(transform.xsl); // 执行转换 transformer.Transform(source.xml, output.html); Console.WriteLine(XSLT 转换完成); } }5.3 Python 示例 (使用 lxml)from lxml import etree 加载 XML 和 XSLT xml_doc etree.parse(source.xml) xslt_doc etree.parse(transform.xsl) 创建转换函数 transform etree.XSLT(xslt_doc) 应用转换 result_tree transform(xml_doc) 输出到文件或字符串 result_tree.write(output.html, pretty_printTrue, encodingutf-8) print(XSLT 转换完成) 也可以直接获取字符串 result_str str(result_tree) print(result_str)