当前位置: 首页 > news >正文

XSLT 实例、元素与转换:从入门到实战

1. 引言

XSLT(可扩展样式表语言转换)是一种用于将 XML 文档转换为其他格式(如 HTML、文本或其他 XML)的语言。它通过 XSLT 样式表定义转换规则,将源 XML 树映射为目标输出树。本文将通过丰富的代码实例,系统讲解 XSLT 的核心元素、转换机制和实战应用。

2. XSLT 基础概念

XSLT 样式表本身是一个 XML 文档,根元素为<xsl:stylesheet><xsl:transform>。它通过 XPath 表达式定位 XML 节点,并使用模板规则描述如何转换这些节点。

一个最简单的 XSLT 样式表结构如下:

<?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> <h2>Hello, XSLT!</h2> </body> </html> </xsl:template> </xsl:stylesheet>

上述样式表匹配文档根节点,输出一个简单的 HTML 页面。下面我们通过一个完整的实例来理解 XSLT 的工作流程。

3. XSLT 实例:图书列表转换

假设我们有一个描述图书信息的 XML 文档,希望通过 XSLT 将其转换为 HTML 表格展示。

3.1 源 XML 文档

<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="编程"> <title lang="zh">XML 入门与实践</title> <author>张三</author> <price>59.00</price> </book> <book category="数据库"> <title lang="zh">SQL 高级查询</title> <author>李四</author> <price>79.00</price> </book> <book category="编程"> <title lang="en">XSLT Cookbook</title> <author>王五</author> <price>99.00</price> </book> </bookstore>

3.2 XSLT 样式表

<?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> </head> <body> <h2>图书信息一览</h2> <table border="1"> <tr> <th>书名</th> <th>作者</th> <th>价格</th> <th>分类</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> <td><xsl:value-of select="@category"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>

3.3 转换结果

上述样式表通过<xsl:for-each>遍历所有book元素,并使用<xsl:value-of>提取子元素和属性的值,最终生成如下 HTML 表格:

<html> <head> <title>图书列表</title> </head> <body> <h2>图书信息一览</h2> <table border="1"> <tr> <th>书名</th> <th>作者</th> <th>价格</th> <th>分类</th> </tr> <tr> <td>XML 入门与实践</td> <td>张三</td> <td>59.00</td> <td>编程</td> </tr> <tr> <td>SQL 高级查询</td> <td>李四</td> <td>79.00</td> <td>数据库</td> </tr> <tr> <td>XSLT Cookbook</td> <td>王五</td> <td>99.00</td> <td>编程</td> </tr> </table> </body> </html>

4. XSLT 核心元素详解

XSLT 提供了丰富的元素用于构建转换规则。下面逐一介绍最常用的核心元素,并给出可运行的代码实例。

4.1 xsl:template 与 xsl:apply-templates

<xsl:template>定义转换规则,<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:template match="/"> <html> <body> <xsl:apply-templates select="bookstore/book"/> </body> </html> </xsl:template> <xsl:template match="book"> <p> <strong><xsl:value-of select="title"/></strong> 作者:<xsl:value-of select="author"/> 价格:<xsl:value-of select="price"/> </p> </xsl:template> </xsl:stylesheet>

当根模板匹配到bookstore/book节点时,会自动调用匹配book的模板,实现节点级递归处理。

4.2 xsl:value-of 与 xsl:text

<xsl:value-of>用于提取节点或表达式的字符串值;<xsl:text>用于输出纯文本内容,可精确控制空白字符。

<xsl:template match="book"> <p> <xsl:text>书名:</xsl:text> <xsl:value-of select="title"/> <xsl:text>(作者:</xsl:text> <xsl:value-of select="author"/> <xsl:text>)</xsl:text> </p> </xsl:template>

4.3 xsl:for-each 与排序

<xsl:for-each>用于循环遍历节点集,可配合<xsl:sort>实现排序输出。

<xsl:template match="/"> <ul> <xsl:for-each select="bookstore/book"> <xsl:sort select="price"><xsl:template match="book"> <p> <xsl:value-of select="title"/> <xsl:if test="price > 80"> (高价图书) </xsl:if> </p> </xsl:template>
<xsl:template match="book"> <p> <xsl:value-of select="title"/> <xsl:choose> <xsl:when test="price > 80"> (高价图书) </xsl:when> <xsl:when test="price > 60"> (中价图书) </xsl:when> <xsl:otherwise> (低价图书) </xsl:otherwise> </xsl:choose> </p> </xsl:template>

4.5 xsl:attribute 与 xsl:element 动态创建

<xsl:attribute>动态添加属性;<xsl:element>动态创建元素,适用于输出结构不固定的场景。

<xsl:template match="book"> <xsl:element name="div"> <xsl:attribute name="class"> <xsl:choose> <xsl:when test="price > 80">high-price</xsl:when> <xsl:otherwise>normal-price</xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:value-of select="title"/> </xsl:element> </xsl:template>

4.6 xsl:variable 与 xsl:param 变量和参数

<xsl:variable>定义局部变量;<xsl:param>定义可被外部传入的模板参数。

<xsl:template match="/"> <xsl:variable name="discount" select="0.8"/> <xsl:for-each select="bookstore/book"> <p> <xsl:value-of select="title"/> 折后价:<xsl:value-of select="price * $discount"/> </p> </xsl:for-each> </xsl:template>
<xsl:template name="book-item"> <xsl:param name="showPrice" select="'true'"/> <p> <xsl:value-of select="title"/> <xsl:if test="$showPrice = 'true'"> (<xsl:value-of select="price"/> 元) </xsl:if> </p> </xsl:template>

4.7 xsl:call-template 与命名模板

<xsl:call-template>按名称调用模板,实现代码复用。

<xsl:template match="/"> <html> <body> <xsl:for-each select="bookstore/book"> <xsl:call-template name="book-item"/> </xsl:for-each> </body> </html> </xsl:template> <xsl:template name="book-item"> <p> <xsl:value-of select="title"/> 作者:<xsl:value-of select="author"/> </p> </xsl:template>

4.8 xsl:number 自动编号

<xsl:number>为节点自动编号,常用于生成目录或列表序号。

<xsl:template match="book"> <p> <xsl:number value="position()" format="1. "/> <xsl:value-of select="title"/> </p> </xsl:template>

4.9 xsl:copy 与 xsl:copy-of 节点复制

<xsl:copy>复制当前节点(不含子节点);<xsl:copy-of>复制节点及其全部子树。

<xsl:template match="book"> <xsl:copy> <xsl:attribute name="source">bookstore</xsl:attribute> <xsl:copy-of select="title"/> </xsl:copy> </xsl:template>

4.10 xsl:output 输出格式控制

<xsl:output>声明输出文档的类型、编码和缩进方式。

<xsl:output method="html" encoding="UTF-8" indent="yes"/>

常用 method 取值包括xmlhtmltext

5. XSLT 转换实战:XML 转 HTML 报表

下面综合运用上述元素,实现一个完整的 XML 转 HTML 报表案例。源数据为员工信息,要求输出带统计信息的报表。

5.1 源 XML

<?xml version="1.0" encoding="UTF-8"?> <company> <department name="研发部"> <employee> <name>赵一</name> <position>高级工程师</position> <salary>25000</salary> </employee> <employee> <name>钱二</name> <position>工程师</position> <salary>18000</salary> </employee> </department> <department name="市场部"> <employee> <name>孙三</name> <position>市场专员</position> <salary>12000</salary> </employee> </department> </company>

5.2 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" indent="yes"/> <xsl:template match="/"> <html> <head> <title>员工报表</title> </head> <body> <h2>公司员工报表</h2> <xsl:apply-templates select="company/department"/> <hr/> <p> <strong>员工总数:</strong> <xsl:value-of select="count(company/department/employee)"/> </p> <p> <strong>平均薪资:</strong> <xsl:value-of select="format-number(sum(company/department/employee/salary) div count(company/department/employee), '¥#,##0.00')"/> </p> </body> </html> </xsl:template> <xsl:template match="department"> <h3><xsl:value-of select="@name"/></h3> <table border="1"> <tr> <th>序号</th> <th>姓名</th> <th>职位</th> <th>薪资</th> </tr> <xsl:for-each select="employee"> <tr> <td><xsl:number value="position()" format="1"/></td> <td><xsl:value-of select="name"/></td> <td><xsl:value-of select="position"/></td> <td><xsl:value-of select="format-number(salary, '¥#,##0')"/></td> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>

5.3 关键点说明

  • count()函数统计节点数量。
  • sum()函数对节点集求和。
  • format-number()函数格式化数字为货币样式。
  • <xsl:number>为每行生成序号。

6. XSLT 转换实战:XML 转 XML 数据重组

XSLT 也常用于 XML 到 XML 的结构重组,例如将扁平结构转换为嵌套结构。

6.1 源 XML(扁平结构)

<?xml version="1.0" encoding="UTF-8"?> <orders> <order id="1001" customer="张三" product="笔记本电脑" quantity="1"/> <order id="1002" customer="李四" product="鼠标" quantity="2"/> <order id="1003" customer="张三" product="键盘" quantity="1"/> </orders>

6.2 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="xml" encoding="UTF-8" indent="yes"/> <xsl:key name="customer-key" match="order" use="@customer"/> <xsl:template match="/"> <customer-orders> <xsl:for-each select="orders/order[generate-id() = generate-id(key('customer-key', @customer)[1])]"> <xsl:sort select="@customer"/> <customer name="{@customer}"> <xsl:for-each select="key('customer-key', @customer)"> <order id="{@id}" product="{@product}" quantity="{@quantity}"/> </xsl:for-each> </customer> </xsl:for-each> </customer-orders> </xsl:template> </xsl:stylesheet>

6.3 转换结果

<?xml version="1.0" encoding="UTF-8"?> <customer-orders> <customer name="张三"> <order id="1001" product="笔记本电脑" quantity="1"/> <order id="1003" product="键盘" quantity="1"/> </customer> <customer name="李四"> <order id="1002" product="鼠标" quantity="2"/> </customer> </customer-orders>

这里使用<xsl:key>generate-id()实现分组,是 XSLT 1.0 中常用的分组技巧。

7. XSLT 转换实战:XML 转纯文本

当输出格式为纯文本时,使用method="text",常用于生成配置文件或日志。

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="/"> <xsl:text>图书清单 </xsl:text> <xsl:text>==================== </xsl:text> <xsl:for-each select="bookstore/book"> <xsl:value-of select="title"/> <xsl:text> | </xsl:text> <xsl:value-of select="author"/> <xsl:text> | </xsl:text> <xsl:value-of select="price"/> <xsl:text> 元 </xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>

输出结果为:

图书清单 ==================== XML 入门与实践 | 张三 | 59.00 元 SQL 高级查询 | 李四 | 79.00 元 XSLT Cookbook | 王五 | 99.00 元

8. 常见问题与调试技巧

8.1 命名空间处理

当源 XML 使用命名空间时,样式表中必须声明相同的命名空间前缀,并在 XPath 中使用该前缀。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:bk="http://www.example.com/bookstore"> <xsl:template match="/"> <xsl:for-each select="bk:bookstore/bk:book"> <p><xsl:value-of select="bk:title"/></p> </xsl:for-each> </xsl:template> </xsl:stylesheet>

8.2 调试建议

  • 使用indent="yes"让输出更易读。
  • 先用简单模板验证 XPath 路径是否正确。
  • 利用<xsl:message>输出调试信息到控制台。
  • 分步转换:先输出 XML,再转换为 HTML,便于定位问题。
<xsl:template match="book"> <xsl:message>正在处理图书:<xsl:value-of select="title"/></xsl:message> <p><xsl:value-of select="title"/></p> </xsl:template>

9. 总结

本文通过丰富的代码实例,系统介绍了 XSLT 的核心元素与转换机制。从最简单的模板匹配,到for-eachchoosevariablekey等高级特性,再到 XML 转 HTML、XML 转 XML、XML 转文本三种典型场景,覆盖了 XSLT 开发的主要知识点。掌握这些内容后,读者可以灵活运用 XSLT 完成各类数据转换任务。

http://www.cnnetsun.cn/news/4313266.html

相关文章:

  • 拿走计算器后,50个LLM原生算术能力评测揭秘
  • DisplayWave:开源macOS显示管理工具,轻松解决外接显示器痛点
  • Obsidian 报错 Vault not found解决方案
  • FreeRTOS任务相关API函数
  • Stable Diffusion实战:从男生照片生成女生形象并与兄弟同框合影
  • 上半年动力储能电池销量暴涨48.6%、小鹏机器人融资9亿美元、新型储能入列十五五:新能源产业的第二增长曲线
  • 2026年AI数字人城市合伙人怎么选|3个维度避开合作陷阱
  • 非计算机专业入门深度学习:避开弯路的高效学习路径
  • Transformer结合强化学习:长时序决策的工程实践与避坑指南
  • MP3转AAC用哪种工具更方便?MP3转AAC的详细操作步骤与避坑注意
  • AI医疗入门指南:医学生从零跑通深度学习全流程
  • MacBook Pro M5 Max 本地大模型实战:从量化到部署的完整指南
  • 解析福州企业级AI自动化获客解决方案优质品牌特点
  • Python进阶:13个你可能不知道但能大幅提升效率的特性
  • AI Agent入门:从真实任务出发,跑通最小闭环
  • Android Studio记事本App开发:从SQLite到RecyclerView的完整项目实战
  • ComfyUI实战:搭建本地生图+视频一体化AI工作流
  • BP神经网络实现6类数字调制信号智能识别
  • 上下文窗口并非越大越好:大模型开发的资源取舍与实战策略
  • DeepSeek Harness接入全解:从API配置到reasoning_content报错排查
  • AI Agent零基础学习路线:从核心概念到日志分析实战
  • 在Ubuntu容器中验证Linux死亡命令:隔离边界与安全实践
  • JavaScript核心知识梳理:从变量到异步请求的入门路线
  • 8款高性价比AI论文平台横向实测,本硕博避坑必备指南
  • CAD批量统一文字大小:SCALETEXT命令快速解决字高不一致问题
  • 机器学习预测钢管混凝土柱承载力:XGBoost与SHAP深度解析
  • Shelf Protocol:电商数据访问的“Robots.txt”协议解析
  • ESP32-S3智能自动化控制器开发:从原型到成品的工程实践指南
  • Codex Harness与SWE-bench:模型评测的可复现性为何如此重要
  • LSTM汽车销量预测实战:从数据处理到调参上线