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

    • 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:value-of(提取值)、xsl:attribute/xsl:element(动态创建属性/元素)、xsl:copy/xsl:copy-of(复制节点)。

定义与作用

前面学的模板和控制结构决定了"处理哪些节点",本节关注"输出什么内容"。XSLT 提供了精确的输出控制指令:

  • xsl:value-of:提取节点的字符串值,输出到结果树
  • xsl:attribute:在输出元素上动态创建属性
  • xsl:element:动态创建输出元素(元素名来自表达式)
  • xsl:text:精确输出文本(保留空白)
  • xsl:copy:浅复制——复制当前节点但不含子节点和属性
  • xsl:copy-of:深复制——复制当前节点及其所有后代和属性

核心原理:浅复制 vs 深复制

图解释 :xsl:copy 只复制当前节点的标签(不含属性和子节点),需要手动用 xsl:apply-templates 复制子内容。xsl:copy-of 一步到位,完整复制整个子树。

语法/结构要点

指令作用示例
xsl:value-of输出节点值<xsl:value-of select="title"/>
xsl:attribute动态创建属性<xsl:attribute name="href">link</xsl:attribute>
xsl:element动态创建元素<xsl:element name="h{level}">heading</xsl:element>
xsl:text精确输出文本<xsl:text> </xsl:text>(保留空白)
xsl:copy浅复制当前节点<xsl:copy><xsl:apply-templates/></xsl:copy>
xsl:copy-of深复制节点及子树<xsl:copy-of select="book"/>
xsl:comment输出注释<xsl:comment>生成时间</xsl:comment>

完整示例:小崔实现 XML→XML 格式升级

场景说明

飞翔科技的后端 小崔 需要把旧版学生 XML 升级为新版格式。变化:元素名 snake_case 改 camelCase、添加 version 属性、移除敏感字段 ssn。

操作前:旧版 XML

<students>
  <student_record id="S001">
    <full_name>崔志远</full_name>
    <major_code>CS</major_code>
    <enroll_year>2023</enroll_year>
    <ssn>123-45-6789</ssn>
  </student_record>
</students>

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" indent="yes"/>

  <!-- 根模板:创建新版根元素 -->
  <xsl:template match="/">
    <xsl:element name="university">
      <xsl:attribute name="version">2.0</xsl:attribute>
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- student_record → student -->
  <xsl:template match="student_record">
    <xsl:element name="student">
      <xsl:attribute name="id">
        <xsl:value-of select="@id"/>
      </xsl:attribute>
      <!-- 拷贝所有子元素,但跳过 ssn -->
      <xsl:apply-templates select="*[not(self::ssn)]"/>
    </xsl:element>
  </xsl:template>

  <!-- full_name → fullName -->
  <xsl:template match="full_name">
    <xsl:element name="fullName">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

  <!-- major_code → majorCode -->
  <xsl:template match="major_code">
    <xsl:element name="majorCode">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

  <!-- enroll_year → enrollYear -->
  <xsl:template match="enroll_year">
    <xsl:element name="enrollYear">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

  <!-- ssn:直接跳过(不输出任何内容) -->
  <xsl:template match="ssn"/>
</xsl:stylesheet>

操作结果:新版 XML

<?xml version="1.0" encoding="UTF-8"?>
<university version="2.0">
  <student id="S001">
    <fullName>崔志远</fullName>
    <majorCode>CS</majorCode>
    <enrollYear>2023</enrollYear>
  </student>
</university>

小崔完成了三件事:①元素名全部改为 camelCase;②根元素改名为 university 并加 version 属性;③敏感字段 ssn 被静默移除。

易错场景

错误一:xsl:copy 后忘记 apply-templates

<!-- ❌ 只复制了外层标签,子内容丢失 -->
<xsl:template match="book">
  <xsl:copy/>
</xsl:template>

<!-- ✅ 浅复制 + 递归处理子节点 -->
<xsl:template match="book">
  <xsl:copy>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

错误二:value-of 和 copy-of 混淆

  • xsl:value-of:输出节点的文本值(去掉所有标签)
  • xsl:copy-of:输出节点的完整 XML(保留所有标签和属性)

面试考点

考点参考答案要点
xsl:copy 和 xsl:copy-of 的区别?copy 浅复制(只复制当前节点标签,不含属性和子节点),copy-of 深复制(含整个子树和属性)
xsl:value-of 和 xsl:copy-of 的区别?value-of 提取字符串值(去标签),copy-of 保留 XML 结构
如何用 XSLT 实现"删除某字段"?为要删除的元素写一个空模板(没有内容),如 <xsl:template match="ssn"/>。这样该元素被匹配但不输出任何内容
上一页
XSLT 控制结构