XSLT(Extensible Stylesheet Language Transformations)是一种用于将 XML 文档转换为其他格式的语言。它可以将 XML 转换为 HTML、文本、其他 XML 格式,甚至可以转换为 PDF 等其他文档格式。
XSLT 的基本概念
XSLT 是 XSL(Extensible Stylesheet Language)的一部分,XSL 包含三个部分:
- XSLT:用于转换 XML 文档
- XPath:用于在 XML 文档中导航
- XSL-FO:用于格式化 XML 文档
XSLT 的基本结构
xml<?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> <body> <h1>Book List</h1> <xsl:apply-templates select="bookstore/book"/> </body> </html> </xsl:template> <!-- 另一个模板 --> <xsl:template match="book"> <div> <xsl:value-of select="title"/> <xsl:text> - </xsl:text> <xsl:value-of select="author"/> </div> </xsl:template> </xsl:stylesheet>
XSLT 常用元素
1. 模板元素
xml<xsl:template match="pattern"> 模板内容 </xsl:template> <xsl:apply-templates select="expression"/>
2. 输出元素
xml<xsl:value-of select="expression"/> <xsl:copy/> <xsl:copy-of select="expression"/> <xsl:text>文本内容</xsl:text>
3. 控制元素
xml<!-- 条件判断 --> <xsl:if test="condition"> 内容 </xsl:if> <!-- 多条件选择 --> <xsl:choose> <xsl:when test="condition1"> 内容1 </xsl:when> <xsl:when test="condition2"> 内容2 </xsl:when> <xsl:otherwise> 默认内容 </xsl:otherwise> </xsl:choose> <!-- 循环 --> <xsl:for-each select="expression"> 内容 </xsl:for-each>
4. 变量和参数
xml<xsl:variable name="varName" select="expression"/> <xsl:param name="paramName" select="expression"/> <xsl:value-of select="$varName"/>
5. 排序
xml<xsl:for-each select="book"> <xsl:sort select="price" order="ascending"/> <xsl:value-of select="title"/> </xsl:for-each>
XSLT 实际应用示例
1. XML 转 HTML
输入 XML(books.xml):
xml<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="web"> <title>XML Guide</title> <author>John Doe</author> <price>39.95</price> </book> <book category="database"> <title>SQL Basics</title> <author>Jane Smith</author> <price>29.99</price> </book> </bookstore>
XSLT 样式表(books.xsl):
xml<?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>Book List</title> <style> table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #4CAF50; color: white; } </style> </head> <body> <h1>Book List</h1> <table> <tr> <th>Title</th> <th>Author</th> <th>Price</th> </tr> <xsl:for-each select="bookstore/book"> <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>
2. XML 转 XML
xml<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <catalog> <xsl:for-each select="bookstore/book"> <item> <name><xsl:value-of select="title"/></name> <writer><xsl:value-of select="author"/></writer> <cost><xsl:value-of select="price"/></cost> </item> </xsl:for-each> </catalog> </xsl:template> </xsl:stylesheet>
3. 条件处理
xml<xsl:template match="book"> <div class="book"> <xsl:attribute name="style"> <xsl:choose> <xsl:when test="price > 30"> color: red; </xsl:when> <xsl:when test="price > 20"> color: blue; </xsl:when> <xsl:otherwise> color: green; </xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:value-of select="title"/> - $<xsl:value-of select="price"/> </div> </xsl:template>
在不同语言中使用 XSLT
1. Java
javaimport javax.xml.transform.*; import javax.xml.transform.stream.*; // 创建转换器工厂 TransformerFactory factory = TransformerFactory.newInstance(); // 创建转换器 StreamSource xsltSource = new StreamSource(new File("books.xsl")); Transformer transformer = factory.newTransformer(xsltSource); // 执行转换 StreamSource xmlSource = new StreamSource(new File("books.xml")); StreamResult htmlResult = new StreamResult(new File("books.html")); transformer.transform(xmlSource, htmlResult);
2. Python(lxml)
pythonfrom 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) # 保存结果 result.write("books.html", pretty_print=True)
3. JavaScript(浏览器)
javascript// 在 XML 文档中引用 XSLT <?xml-stylesheet type="text/xsl" href="books.xsl"?> // 或者在 JavaScript 中使用 const xsltProcessor = new XSLTProcessor(); const xsltDoc = document.implementation.createDocument("", "", null); xsltDoc.async = false; xsltDoc.load("books.xsl"); xsltProcessor.importStylesheet(xsltDoc); const xmlDoc = document.implementation.createDocument("", "", null); xmlDoc.async = false; xmlDoc.load("books.xml"); const result = xsltProcessor.transformToDocument(xmlDoc);
XSLT 高级特性
1. 模板模式
xml<xsl:template match="book" mode="summary"> <summary><xsl:value-of select="title"/></summary> </xsl:template> <xsl:template match="book" mode="detail"> <detail> <title><xsl:value-of select="title"/></title> <author><xsl:value-of select="author"/></author> </detail> </xsl:template> <xsl:apply-templates select="book" mode="summary"/>
2. 命名模板
xml<xsl:template name="formatPrice"> <xsl:param name="price"/> $<xsl:value-of select="format-number($price, '#,##0.00')"/> </xsl:template> <xsl:call-template name="formatPrice"> <xsl:with-param name="price" select="price"/> </xsl:call-template>
3. 键和索引
xml<xsl:key name="book-by-author" match="book" use="author"/> <xsl:for-each select="book[count(. | key('book-by-author', author)[1]) = 1]"> <author><xsl:value-of select="author"/></author> </xsl:for-each>
XSLT 最佳实践
- 使用模板匹配:优先使用模板匹配而不是 for-each
- 避免深层次嵌套:保持 XSLT 代码的可读性
- 使用变量:避免重复计算
- 优化 XPath:使用高效的 XPath 表达式
- 模块化设计:将复杂的转换分解为多个模板
XSLT 是处理 XML 数据转换的强大工具,掌握 XSLT 可以大大提高 XML 数据处理的效率和灵活性。