乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • XML 基础语法

    • XML 概述
    • XML 文档结构
    • XML 元素
    • XML 属性
    • XML 语法规则
    • XML 命名空间
    • XML 注释与处理指令
  • DTD 与文档验证

    • DTD 概述
    • DTD 元素声明
    • DTD 属性声明
    • DTD 实体声明
    • DTD 元素与属性对比
    • DTD 完整示例
  • XML Schema 定义

    • XML Schema 概述
    • XSD 简单类型
    • XSD 复杂类型
    • XSD 命名空间与引用
  • XPath 节点定位

    • XPath 概述
    • XPath 路径表达式
    • XPath 谓词与函数
  • XSLT 转换

    • XSLT 概述
    • XSLT 模板与匹配
    • XSLT 控制结构
    • XSLT 输出控制
  • XML 解析技术

    • XML 解析概述
    • DOM 解析
    • SAX 解析
    • StAX 解析
    • XML 与 Java — JAXP
  • XML 在 Java 中的应用

    • Spring XML 配置
    • MyBatis XML 映射
    • pom.xml 与 Maven
    • web.xml 配置详解
  • 现代数据格式对比

    • XML 与 JSON 对比
    • XML 与 YAML 对比
  • XML 显示与浏览器集成

    • XML 在浏览器中的显示
    • XMLHttpRequest 与 AJAX
    • 服务器端 XML 处理
  • XML 进阶查询与链接

    • XQuery 查询语言
    • XLink 超链接
    • XML 验证工具使用
  • XML Web 服务(选读)

    • XML Web 服务概述
    • SOAP 协议详解
    • WSDL 服务描述
    • RSS 内容聚合
    • RDF 资源描述框架

XSLT 控制结构

本章定位 :掌握 XSLT 的条件判断和循环结构——xsl:if(单路条件)、xsl:choose/when/otherwise(多路分支)、xsl:for-each(循环遍历)和 xsl:sort(排序)。

定义与作用

XSLT 是一种声明式语言,但实际转换中经常需要条件逻辑和循环。XSLT 提供了四种控制结构:

  • xsl:if:单路条件(只有 if,没有 else)
  • xsl:choose/when/otherwise:多路分支(if-elseif-else)
  • xsl:for-each:遍历节点集
  • xsl:sort:排序

注意:XSLT 的 if 没有 else 分支——这是它与传统编程语言最大的语法差异,需要多路分支时必须用 choose/when/otherwise。

核心原理:控制流对比

三种控制流程各有用途——if 最简单但无 else,choose 是多路选择,for-each 可配合 sort 实现排序遍历。

语法/结构要点

xsl:if(单路条件)

<xsl:if test="price > 30">
  <strong>贵!</strong>
</xsl:if>

xsl:choose(多路分支)

<xsl:choose>
  <xsl:when test="price > 50">高档</xsl:when>
  <xsl:when test="price > 30">中档</xsl:when>
  <xsl:otherwise>经济</xsl:otherwise>
</xsl:choose>

xsl:for-each + xsl:sort

<xsl:for-each select="bookstore/book">
  <xsl:sort select="price" data-type="number" order="ascending"/>
  <p><xsl:value-of select="title"/> — <xsl:value-of select="price"/></p>
</xsl:for-each>

完整示例:黄俪用控制结构生成报表

场景说明

飞翔科技的测试 黄俪 要为测试结果 XML 生成一份 HTML 报告。需求:按等级分组(高优先级先显示)、通过的标绿、失败的标红,最后统计通过率。

XML 数据

<test-results>
  <case id="TC001" priority="high" status="pass">登录功能</case>
  <case id="TC002" priority="low" status="fail">界面字体</case>
  <case id="TC003" priority="high" status="fail">支付回调</case>
  <case id="TC004" priority="medium" status="pass">搜索过滤</case>
  <case id="TC005" priority="low" status="pass">分页导航</case>
</test-results>

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"/>

  <xsl:template match="/">
    <html><body>
      <h2>测试报告</h2>

      <!-- 统计 -->
      <p>总用例: <xsl:value-of select="count(//case)"/></p>
      <p>通过: <xsl:value-of select="count(//case[@status='pass'])"/></p>
      <p>失败: <xsl:value-of select="count(//case[@status='fail'])"/></p>

      <!-- 按优先级排序 -->
      <table border="1">
        <tr><th>用例</th><th>优先级</th><th>结果</th></tr>
        <xsl:for-each select="test-results/case">
          <xsl:sort select="
            string-length(
              substring-before('highmediumlow', @priority)
            )" data-type="number" order="ascending"/>

          <xsl:choose>
            <xsl:when test="@status='pass'">
              <tr style="background-color:#d4edda;">
                <td><xsl:value-of select="."/></td>
                <td><xsl:value-of select="@priority"/></td>
                <td>通过</td>
              </tr>
            </xsl:when>
            <xsl:otherwise>
              <tr style="background-color:#f8d7da;">
                <td><xsl:value-of select="."/></td>
                <td><xsl:value-of select="@priority"/></td>
                <td>失败</td>
              </tr>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
      </table>
    </body></html>
  </xsl:template>
</xsl:stylesheet>

操作结果

生成的 HTML 报告中:

  • 高优先级用例排在前面(TC001、TC003)
  • 通过用例绿色背景,失败用例红色背景
  • 顶部显示统计:总5个,通过3个,失败2个

易错场景

错误一:以为 xsl:if 有 else

<!-- ❌ XSLT 没有 else -->
<xsl:if test="@status='pass'">通过</xsl:if>
<xsl:else>失败</xsl:else>    <!-- 语法错误! -->

<!-- ✅ 用 choose/when/otherwise -->
<xsl:choose>
  <xsl:when test="@status='pass'">通过</xsl:when>
  <xsl:otherwise>失败</xsl:otherwise>
</xsl:choose>

错误二:xsl:sort 位置错误

xsl:sort 必须是 xsl:for-each 或 xsl:apply-templates 的 第一个子元素 。

<!-- ✅ -->
<xsl:for-each select="book">
  <xsl:sort select="price"/>
  <p>...</p>
</xsl:for-each>

<!-- ❌ sort 不在第一个 -->
<xsl:for-each select="book">
  <p>...</p>
  <xsl:sort select="price"/>
</xsl:for-each>

面试考点

考点参考答案要点
XSLT 的 if 为什么没有 else?XSLT 是声明式语言,设计上倾向于用模板匹配(多模板 + 不同 match)实现分支。需要 else 时用 xsl:choose/when/otherwise
for-each 和 apply-templates 的选择原则?for-each 适合简单的遍历输出(如表格行);apply-templates 支持多模板分派和递归,适合复杂、层次化的转换
xsl:sort 的排序类型支持哪些?data-type 支持 text(字典序)和 number(数值序),order 支持 ascending 和 descending。多个 sort 可级联
上一页
XSLT 模板与匹配
下一页
XSLT 输出控制